谁能解释一下 Paul Graham 的 ANSI Common Lisp 第 110 页中的示例吗?
该示例尝试解释使用 &rest 和 lambda 来创建函数式编程工具。其中之一是组成函数参数的函数。我找不到任何解释它是如何工作的。代码如下:
(defun compose (&rest fns)
(destructuring-bind (fn1 . rest) (reverse fns)
#'(lambda (&rest args)
(reduce #'(lambda (v f) (funcall f v))
rest
:initial-value (apply fn1 args)))))
用法是:
(mapcar (compose #'list #'round #'sqrt)
'(4 9 16 25))
输出是:
((2) (3) (4) (5))
对我来说,2 号线和 6 号线看起来特别神奇。
The compose
函数返回一个closure从最后到第一个调用每个函数,并将每个函数调用的结果传递给下一个函数。
调用导致的关闭(compose #'list #'round #'sqrt)
首先计算其参数的平方根,将结果四舍五入到最接近的整数,然后创建结果列表。使用 say 3 作为参数调用闭包相当于评估(list (round (sqrt 3)))
.
The 解构绑定评估(reverse fns)
表达式来获取参数compose
以相反的顺序,并将结果列表的第一项绑定到fn1局部变量和结果列表的其余部分rest局部变数。因此fn1保存最后一项fns, #'sqrt
.
The reduce称每个fns
具有累积结果的函数。这:initial-value (apply fn1 args)
提供初始值reduce
函数并支持使用多个参数调用闭包。不需要多个参数,compose
可以简化为:
(defun compose (&rest fns)
#'(lambda (arg)
(reduce #'(lambda (v f) (funcall f v))
(reverse fns)
:initial-value arg)))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)