Lambda里面的函数定义Scheme

时间:2016-11-20 22:21:10

标签: lambda scheme racket higher-order-functions

(define (fn lst)
  (filter (lambda (item) (not (symbol=? item 'sym))) lst))

我们传入lst,但在(lambda (item) (not (symbol=? item 'sym)))内,我们的变量lst从未使用过。评价

1 个答案:

答案 0 :(得分:4)

您发布的代码片段结合了两个概念,这些概念可以单独解释(并且可能更有意义): lambda表达式高阶函数。< / p>

Lambda表达式

在Scheme / Racket中,函数是普通值,就像数字或列表一样。要创建一个数字,只需输入一个,例如325。要创建列表,请使用list函数,例如(list 2 4 6)。要创建函数,请使用lambda表单。

通常,在定义函数时,使用define。例如,这是一个向数字加1的函数:

(define (add1 x)
  (+ x 1))

但这只是一种简写语法。编写上述定义的完整方式如下:

(define add1
  (lambda (x)
    (+ x 1)))

如您所见,它使用lambda

如果lambda缩写更短且更容易阅读,为什么直接使用define会有用?那么,要理解这一点,你必须考虑更高阶的函数。

高阶函数

大多数函数采用简单值并生成简单值。例如,上面的add1函数将一个数字作为参数,并生成一个数字作为结果。但是,请记住上面我提到函数也是值。因此,函数实际上可以接受其他函数作为参数,甚至可以生成其他函数作为结果。这些函数称为“高阶函数”。

filter函数是一个高阶函数。它需要一个函数和一个列表,它使用该函数来选择应该在结果中保留哪些元素。例如,它可用于选择列表中的所有偶数:

> (filter even? (list 1 2 3 4 5))
'(2 4)

请注意even?是一个函数,它作为参数传递给filter。这完全没问题,而且它实际上非常有用! Scheme / Racket中有许多高阶函数,这些函数是“功能”风格编程的重要部分。例如,map函数允许您提供应用于列表的每个元素的函数:

> (map add1 (list 1 2 3 4 5))
'(2 3 4 5 6)

当然,这一切都很好,但是如果你想在列表的每个元素中添加1以外的数字呢?好吧,你总是可以定义一个添加了正确数量的新功能:

> (define (add25 x)
    (+ x 25))
> (map add25 (list 1 2 3 4 5))
'(26 27 28 29 30)

然而,这将是非常愚蠢的。如果您必须使用define为所有数字命名,而不是直接在程序中输入名称。对于只使用一次的小而简单的函数,不需要给它们命名。为此,您可以直接使用lambda表单:

> (map (lambda (x) (+ x 25))
       (list 1 2 3 4 5))
'(26 27 28 29 30)

这就是您问题中的代码段中发生的情况。你可以给内部lambda一个名字,如:

(define (not-an-apple? item)
  (not (symbol=? item 'apple)))

(define (eat-apples lst)
  (filter not-an-apple? lst))

但是,在这种情况下,只需编写内联函数就更容易,因为具有单独的not-an-apple?函数可能不是非常有用。