Racket 在这种情况下,我为什么需要评估lambda
以下代码是一个Racket 在这种情况下,我为什么需要评估lambda,racket,Racket,以下代码是一个# 我不知道为什么会这样。我需要应用lambda表达式 #lang racket (require threading) (~>> 1 ((lambda (x) x)) ) 只有这样,它才会产生1,这是我所期望的线程包提供的宏,它将前面的表达式插入后面的表达式中。当它看到这样的模式时: #lang racket (require threading) (~>> a (f b _)) 它在第二个子表单中查找。,并将a插入表单中的(f b
#
我不知道为什么会这样。我需要应用lambda表达式
#lang racket
(require threading)
(~>> 1
((lambda (x) x))
)
只有这样,它才会产生
1
,这是我所期望的线程包提供的宏,它将前面的表达式插入后面的表达式中。当它看到这样的模式时:
#lang racket
(require threading)
(~>> a
(f b _))
它在第二个子表单中查找。
,并将a
插入表单中的(f b a)
位置
更让人困惑的是有一个速记。如果\
位于~>
子表单的末尾,则可以忽略它。当它看到像(fb)
这样没有(fb)
的东西时,它会在末尾插入它,就好像你写了(fb)
。这就是lambda案例中发生的情况,它将您的语法解释为等价于(lambda(x)x)
插入1
后的结果是(lambda(x)x1)
。那不是你所期望的
你想要什么
从您对lambda函数的使用和期望来看,似乎不需要这种复杂的宏行为;您只希望它将它们作为函数应用。所需的线程形式只需将后面的表达式应用于前面表达式的结果,将(~>a(fb))
转换为((fb)a)
。这个更简单的版本由软件包提供
您可以将这个更简单的~>
与一个简写的lambda包(如fancy app
)结合起来,使这样的表达式看起来更漂亮
(require fancy-app)
(~> 1
(+ _ 10)
(expt _ 4)
number->string
(printf "~a seconds" _))
;=outputs> 14641 seconds
这种常见的混乱让我担心线程
是一种不合适的功能,尤其是因为Racket允许像这样的灵活应用程序。您认为值得在线程化的文档中添加免责声明吗?我认为文档可能更清晰。从第一个示例看,它似乎将(~>1 add1 sqrt)
转换为(sqrt(add1))
,然后下一个带有字节引用的示例没有太多解释。我不确定,您应该如何引入这样一个概念,即它以不同的方式对待带括号的表达式?好的,接下来的整个部分(第1.2节)用bytes ref
解释了这个示例。也许这需要说得更清楚些?虽然有人简要地提到过,f
相当于(f)
这一点,也许需要更加突出?对于仅仅看了前几个例子的人来说,开头的f
相当于(f)
的解释是没有意义的。你需要弄清楚,在前两个例子中,它特别处理带括号的表达式。这很公平,是的。当我有时间的时候,我可以试着重写一些文档。
#lang racket
(require point-free)
(~> 1
(lambda (x) x))
;=> 1
(~> 1
(lambda (x) (+ x 10))
(lambda (x) (expt x 4))
number->string
(lambda (x) (printf "~a seconds" x)))
;=outputs> 14641 seconds
(require fancy-app)
(~> 1
(+ _ 10)
(expt _ 4)
number->string
(printf "~a seconds" _))
;=outputs> 14641 seconds