在这种情况下,为什么我需要评估lambda

时间:2017-02-16 09:58:47

标签: racket

以下代码与#<procedure>

相关
#lang racket
(require threading)
(~>> 1
     (lambda (x) x)
)

我不确定为什么会这样。我需要应用lambda表达式

#lang racket
(require threading)
(~>> 1
     ((lambda (x) x))
)

只有这样才会产生1这就是我所期待的

1 个答案:

答案 0 :(得分:2)

threading包提供~>>作为宏,它将先前的表达式插入到后面的表达式中。当它看到这样的模式时:

#lang racket
(require threading)
(~>> a
     (f b _))

它在第二个子表单中找到_,并将a插入表单(f b a)中的该位置。

让人感到困惑的是,有一个简写。如果_位于~>>中的子表单的末尾,则可以省略它。当它看到(f b)之类没有_的内容时,它会在最后插入它,就好像你写了(f b _)一样。这就是lambda案例中发生的情况,它将您的语法解释为等同于(lambda (x) x _)

插入1后的结果为(lambda (x) x 1)。那不是你所期望的。

你想要什么

从你使用lambda函数和你的期望,似乎你不需要这种复杂的宏观行为;你只是想让它作为函数应用它们。您想要的线程化表单只会将后面的表达式应用于之前的表达式,将(~> a (f b))转换为((f b) a)。这个更简单的版本由point-free包提供为~>

#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

你可以将这个更简单的~>与一个简写的lambda包(例如fancy-app)结合起来,使这样的表达式看起来更好。

(require fancy-app)
(~> 1
    (+ _ 10)
    (expt _ 4)
    number->string
    (printf "~a seconds" _))
;=outputs> 14641 seconds