计划中lambda的重点是什么?

时间:2010-05-31 11:04:09

标签: lambda scheme let

我正在学习计划。我知道如何使用lambda和let表达式。

然而,我正在努力弄清楚使用lambda的重点是什么。你能不能用lambda做任何事情吗?

看一个lambda表达式是比let更好的选择的例子会特别有用。

还有一件事 - 是否还有让let比lambda更有用的情况?如果是这样的例子也会很好。

编辑:我也对对比定义和lambda感兴趣,因为它们似乎执行类似的任务。


更新

感谢大家的帮助。在阅读了你的答案之后,我做了更多的研究lambda / let / define,现在对它的了解要好得多。

我遇到了一个很酷的lambda用法的好例子 - 从程序中返回匿名函数。例如,下面的过程operateTwice返回一个匿名函数,该函数基于传入过程的参数:

(define operateTwice
  (lambda (op1 op2)
    (lambda (x y)
      (op2 (op1 x y) y))))

((operateTwice * +) 2 3) ;equivalent to: (+ (* 2 3) 3), or in standard notation 2*3+3

输出:

9

6 个答案:

答案 0 :(得分:44)

letlambda

E.g。

(let ((x 1))
  body)

可以翻译成

((lambda (x) body) 1)

此外,在Scheme 中,所有控件和环境结构都可以由lambda表达式和lambda的应用程序表示。

因此,lambdalet更强大,并构成了Scheme中许多有趣构造的基础。

关于definelambda,顶级define会为顶级环境添加绑定。

写作时

(define (f x)
  body)
你真的在说

(define f (lambda (x) body))

嵌套定义被翻译成letrec,也可以使用lambdas重写。

所以,再次,很多Scheme结构可以使用lambda转换成某些东西,因此你真的很了解lambda

答案 1 :(得分:13)

如果要创建一个函数将其用作另一个函数的参数(例如lambda),则使用map,但实际上并不想命名该函数。 / p>

例如,如果要为列表中的每个数字添加42,则可以执行以下操作:

(define (add42 x) (+ x 42))
(map add42 (list 1 2 3 4))

但是如果你不想给你只使用过一次的函数命名,你可以这么做:

(map (lambda (x) (+ x 42)) (list 1 2 3 4))

答案 2 :(得分:4)

实际上,它只是Lambda表达式的简写。 以下两个表达式是等效的:

(let ((alpha 7)) (* 5 alpha))

((lambda (alpha) (* 5 alpha)) 7)

Lambda遵循语言的哲学,即一切都应该看起来像一个数学函数。但在实践中,如果变量太多,让我们更容易弄清楚发生了什么。想象一下10个变量,它们的值在Lambda块之后定义,并且你试图将每个变量与变量名称相匹配,让变量值放在它们的名称旁边,方便程序员使用,但更少符合功能编程哲学。

Lambda可用于从更高阶函数返回函数,但是不能这样做。例如:

(define (plus-list x)
  (cond ((number? x)
         (lambda (y) (+ (sum-n x) y)))
        ((list? x)
         (lambda (y) (+ (sum-list x) y)))
        (else (lambda (x) x))
        ))

> ((plus-list 3) 4)
10
> ((plus-list '(1 3 5)) 5)
14
> ((plus-list 'a) 5)
5

Lambda也可用于将函数传递给函数:

>(map (lambda (x) (+ 1 x)) '(-1 2 -3))
(0 3 -2)

答案 3 :(得分:3)

lambda创建新的匿名函数,当然每次使用时都会对它们进行评估。

让我们为值创建临时名称,并设置一次以便在let表单定义的范围内使用。

他们是非常不同的野兽。

一些例子:

  

(lambda(x)(* 5 x))

     

     

(let([x 2])(* 5 x))   10   (let([f(lambda(x)(* 5 x))])(f 2))   10

第一个表单创建一个乘以5的函数

第二种形式将2分配给x并将其乘以5得到10

第三个我们使用1的函数(其多数为5)并将其作为参数调用2,结果也是10

答案 4 :(得分:3)

在Scheme中,过程(或函数)是第一类对象,如列表,数字或字符串。要创建列表文字,请使用名为list的原语:

> (define marks (list 33 40 56))
> marks
> (33 40 56)

就像这样,要创建一个过程,你可以使用lambda原语(或特殊形式):

> (define add-marks (lambda (m) (apply + m)))
> (add-marks marks)
> 129

由于过程是主要的抽象形式,Scheme为define提供了快捷方式,以便轻松绑定新过程:

> (define (add-marks m) (apply + m))

除此之外,过程就像所有其他第一类对象一样。它们可以作为参数传递给其他过程,并且过程可以评估以生成(或返回)另一个过程。

答案 5 :(得分:1)

你可以这样认为...... 您创建一个使用另一个函数的函数 但是你想让事情更加模块化,所以你要做的就是把第二个函数作为第一个函数的参数调用,这样你就可以在需要其他功能的时候改变第二个函数...... 希望有意义