Racket 中的 Lambda 解释

标签 lambda scheme lisp racket

我试图了解 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))

…我们正在调用 testx 值为 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/

相关文章:

scheme - 使用 R5RS 方案找到哈代-拉马努金数。请在习语和计算方面提出改进建议。

lisp - scheme中 'assoc'函数的时间复杂度是多少?

algorithm - 逆向算法LISP的实现

c++ - 如何在 Qt 中最好地存储动态创建的小部件的数据

c++ - Boost echo 服务器示例并在 lambda 中捕获 this 和 shared_from_this()

c# - 在 KeyValuePair 键上相交列表?

scheme - 方案解释器中的向上箭头发送 ^[[A 而不是返回历史

multithreading - 在为 Runnable 提供 lambda 时,为什么我不必重写 run 方法?

scheme - 有在 Racket 中打印的想法吗?

lisp - LISP 中的 GUI 编程?