我试图了解 lambda 在 Racket 中的使用,但我仍然不清楚。我知道它们是未命名(匿名)函数,但为什么这样好呢?我需要从其他函数访问我的函数,那么我该如何调用它们???请解释下面的小程序以及为什么使用 lambda 更好?谢谢。
; why is this better than below???
(define test
(lambda (x)
(lambda (y)
(+ x y))))
(define add27
(test 27))
; what's wrong with this???
(define (addTest x)
(+ x 27))
> (add27 2)
29
> (addTest 2)
29
最佳答案
在 Racket(和其他函数式编程语言)中,lambda
非常有用,当您想将一个内联的一次性函数作为参数传递而不先定义它时。例如,假设我们想要对数字列表进行平方。我们可以走很远的路,先定义一个 square
函数,然后使用 map
:
(define (square x)
(* x x))
(map square '(1 2 3 4 5))
=> '(1 4 9 16 25)
……或者我们可以简单地传递一个lambda
,像这样:
(map (lambda (x) (* x x))
'(1 2 3 4 5))
=> '(1 4 9 16 25)
如您所见,在某些情况下我们不需要引用函数的名称。当然,如果 lambda
表示的过程将在多个部分中重复使用,或者如果它是递归的,那么给它起一个名字是有意义的(这样它就不再是匿名的):
(define square
(lambda (x) (* x x)))
上面相当于开头第一个square
的定义。事实上,第一个定义只是定义函数的语法糖,但最终所有函数都是lambdas!
现在让我们看看你的例子。在这里,我们以稍微不同的方式使用了 lambda
,并且还举例说明了为什么它们有用 - 我们不仅定义了一个函数,而且还返回了一个函数:
(define test
(lambda (x)
(lambda (y)
(+ x y))))
这样写可能会更清楚一点(等价的,原因如前所述):
(define (test x)
(lambda (y)
(+ x y)))
或者更短——在 Racket 中我们也可以使用这个语法来达到同样的目的:
(define ((test x) y)
(+ x y))
这并不是说这是一种更好(或更差)定义函数的方式——这是不同的东西!我们正在定义一个名为 test
的过程,它接收参数 x
并作为结果返回一个新的匿名函数,该函数又将接收参数 y
。现在,在这些行中:
(define add27
(test 27))
…我们正在调用 test
,x
值为 27
,返回匿名函数,我们命名 函数 add27
。还记得作为参数 y
接收的 lambda
吗?现在 lambda
已命名为 add27
- 这是 currying 的示例.想一想:test
是一个函数,用于生成将固定值 x
添加到给定参数 y
的函数,这解释了为什么这有效:
(add27 2)
=> 29
另一方面,这个函数总是将 27
添加到它的参数中,无法更改它:
(define (addTest x)
(+ x 27))
(addTest 2)
=> 29
你看出区别了吗? test
允许我们生成添加任意值的新函数,而 addTest
总是添加一个固定值,27
。如果您想添加 100
怎么办?使用 test
这很简单:
(define add100 (test 100))
但是addTest
不能改,我们需要写一个新的函数:
(define (addTest100 x)
(+ x 100))
我希望这能澄清一些事情,如有任何关于我的回答的其他问题,请随时在评论中提出。
关于 Racket 中的 Lambda 解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25696063/