我们在 P.Graham 的“ANSI Common Lisp”(第 110 页)中找到了这个函数构建器来实现组合。
参数是 n>0 带引号的函数名称。我不完全理解它,所以我将在这里引用代码并在下面指出我的问题:
(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)))))
要组合的参数列表被反转并解包,其(现在是第一个)元素绑定到“fn1”,其余元素绑定到“rest”。
最外层 lambda 的主体是一个reduce: (funcall fi (funcall fi-1 ... ) ),其中操作数按倒序排列以恢复初始操作数。
1)最外层的lambda表达式的作用是什么?也就是说,它从哪里获取“args”?它是指定为 destructuring-bind 第一个参数的数据结构吗?
2) 最里面的 lambda 从哪里获取它的两个参数?
我的意思是我可以理解代码的作用,但词法范围对我来说仍然有点神秘。
期待任何和所有评论!
提前致谢,
//马可
如果您首先考虑几个实际示例,可能会更容易:
(defun compose1 (a)
(lambda (&rest args)
(apply a args)))
(defun compose2 (a b)
(lambda (&rest args)
(funcall a (apply b args))))
(defun compose3 (a b c)
(lambda (&rest args)
(funcall a (funcall b (apply c args)))))
所以最外面的lambda
是返回值:一个接受任何参数的函数,它的作用是应用最后一个函数,并根据从最后一个函数获得的结果以相反的顺序链接所有其他函数。
Note: compose1
可以更简单地定义为(defun compose1 (a) a)
.
一个稍微等效但效率较低的版本可能是
(defun compose (&rest functions)
(if (= (length functions) 1)
(car functions)
(lambda (&rest args)
(funcall (first functions)
(apply (apply #'compose (rest functions))
args)))))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)