【问题标题】:Lambda inside function definition SchemeLambda内部函数定义Scheme
【发布时间】:2016-11-20 22:21:10
【问题描述】:
(define (fn lst)
  (filter (lambda (item) (not (symbol=? item 'sym))) lst))

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

【问题讨论】:

  • 请不要完全改变您的问题。这使人们花时间写的答案无效。如果您有新问题,请提出新问题。

标签: lambda scheme racket higher-order-functions


【解决方案1】:

您发布的代码 sn-p 结合了两个可以单独解释的概念(这样可能更有意义):lambda 表达式高阶函数 .

Lambda 表达式

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

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

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

但这实际上只是一种简写语法。写出上述定义的完整方式如下所示:

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

如您所见,它使用lambda

如果define 简写更短且更易于阅读,为什么直接使用lambda 会有用?好吧,要理解这一点,您必须考虑高阶函数。

高阶函数

大多数函数采用简单值并产生简单值。例如,上面的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)

这就是您问题的 sn-p 中发生的情况。您可以为内部 lambda 命名,如下所示:

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

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

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

【讨论】:

  • @AnamayaGarodia filter 函数只是将提供的函数应用于列表中的每个元素; item 恰好是该函数的第一个参数的名称。
  • @AnamayaGarodia 实际上,是的,但不仅仅是第一个元素。在内部,filter 是递归的。
猜你喜欢
  • 1970-01-01
  • 2014-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-23
  • 1970-01-01
相关资源
最近更新 更多