为什么这个 reduce 函数调用在 Common Lisp 中不起作用?
Why this reduce function call does not work in Common Lisp?
使用 Common Lisp (SBCL),我可以在 REPL 中成功求值:
CL-USER> (reduce #'+ '(1 2 3 4))
10
然而,这失败了:
> (reduce #'(lambda (e) (+ e 100)) '(1 2 3 4))
调试器抛出错误:
invalid number of arguments: 2
我期待的是累积效应,所以总和是 110
。
怎样才能达到预期的效果?我需要使用 reduce
以外的其他东西吗?
reducing 函数必须接受两个参数。您的 lambda 函数只接受一个。即使它有效,它也会将 100
添加到列表中每一步添加的结果中。
你的意思是指定初始值。最简单的 hacky 方法就是将它添加到您的列表中,例如
> (reduce #'+ (cons 100 '(1 2 3 4)))
110
正确的方法,the specs, is to explicitly specify it with the :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
您可能还想再添加一个 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
使用 Common Lisp (SBCL),我可以在 REPL 中成功求值:
CL-USER> (reduce #'+ '(1 2 3 4))
10
然而,这失败了:
> (reduce #'(lambda (e) (+ e 100)) '(1 2 3 4))
调试器抛出错误:
invalid number of arguments: 2
我期待的是累积效应,所以总和是 110
。
怎样才能达到预期的效果?我需要使用 reduce
以外的其他东西吗?
reducing 函数必须接受两个参数。您的 lambda 函数只接受一个。即使它有效,它也会将 100
添加到列表中每一步添加的结果中。
你的意思是指定初始值。最简单的 hacky 方法就是将它添加到您的列表中,例如
> (reduce #'+ (cons 100 '(1 2 3 4)))
110
正确的方法,the specs, is to explicitly specify it with the :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
您可能还想再添加一个 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