(define (fn lst)
(filter (lambda (item) (not (symbol=? item 'sym))) lst))
我们传入lst
,但在(lambda (item) (not (symbol=? item 'sym)))
内,我们的变量lst
从未使用过。评价
答案 0 :(得分:4)
您发布的代码片段结合了两个概念,这些概念可以单独解释(并且可能更有意义): lambda表达式和高阶函数。< / p>
在Scheme / Racket中,函数是普通值,就像数字或列表一样。要创建一个数字,只需输入一个,例如3
或25
。要创建列表,请使用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?
函数可能不是非常有用。