[英]Lambda in Racket Explained
我试图理解在球拍中使用lambda,我仍然不清楚。 我知道他们是无名(匿名)功能,但为什么这么好? 我需要从其他函数访问我的函数,所以我怎么称呼它们? 请解释下面的小程序,为什么使用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
是一个函数,用于生成向给定参数y
添加固定值x
的函数,这解释了为什么这样可行:
(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))
我希望这可以澄清一些事情,随时可以在评论中询问有关我答案的任何其他问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.