如何解决为什么这个 reduce 函数调用在 Common Lisp 中不起作用?
使用 Common Lisp (SBCL),我可以在 REPL 中成功评估:
CL-USER> (reduce #'+ '(1 2 3 4))
10
然而,这失败了:
> (reduce #'(lambda (e) (+ e 100)) '(1 2 3 4))
调试器抛出错误:
无效的参数数量:2
我期待累积效应,所以总和为 110
。
我怎样才能达到预期的效果?我需要使用除 reduce
之外的其他东西吗?
解决方法
reduction 函数必须接受两个参数。您的 lambda 函数只接受一个。即使它有效,它也会将 100
添加到列表中每一步添加的结果中。
您的意思是指定初始值。最简单的 hacky 方法就是将其添加到您的列表中,例如
> (reduce #'+ (cons 100 '(1 2 3 4)))
110
使用 the specs 的正确方法是使用 :initial-value
keyword parameter 明确指定它:
> (reduce #'+ '(1 2 3 4) :initial-value 100)
110
如果您确实想在每个缩减步骤中添加 100
,
> (reduce #'(lambda (a x) (+ 100 a x)) '(1 2 3 4))
310
您可能还想通过将 is 指定为 100
来再添加一个 :initial-value
。
调用 (reduce #'f '(1 2 3 4))
会计算
(f (f (f 1 2) 3) 4)
例如
>>> (reduce #'(lambda (a b) (cons a b)) '(1 2 3 4))
(((1 . 2) . 3) . 4)
因此,您传递给 reduce
的函数需要接受两个参数。首先使用序列的前两个元素调用此函数。然后使用前一个调用的结果和序列中的下一个元素调用该函数,依此类推(参见 [CLHS reduce])。要获得所有元素的总和,您需要调用以下代码:
>>> (reduce #'(lambda (a b) (+ a b)) '(1 2 3 4))
10
reduce
的行为可以通过提供初始值来改变。打电话
(reduce #'f '(1 2 3 4) :initial-value 100)
将计算以下内容:
(f (f (f (f 100 1) 2) 3) 4)
因此,如果您想获得所需的结果,可以使用:
>>> (reduce #'+ '(1 2 3 4) :initial-value 100)
110
要将每个数字加 100 然后计算总和,您可以使用 reduce
和 mapcar
的组合,这是函数式编程中的常见模式:
>>> (reduce #'+ (mapcar #'(lambda (a) (+ a 100)) '(1 2 3 4)))
410
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。