Functional programming 在Lisp中对mapcon应用append
Lisp函数Functional programming 在Lisp中对mapcon应用append,functional-programming,lisp,common-lisp,map-function,Functional Programming,Lisp,Common Lisp,Map Function,Lisp函数G的定义如下: (defun g (l) (mapcon #'list l)) 计算表单(apply#'append(mapcon#'g'(12))的结果是什么 证明答案的正确性 我已经看到mapcon与ncoc和cdr一起工作,但最终的答案将是(12),我不知道如何正确解释它。请帮忙。首先,我们打电话: (mapcon (lambda (list) (print list) nil) '(1 2)) 由于匿名函数始终返回NIL,因此结果列表为NIL;调用打印以下内容:
G
的定义如下:
(defun g (l)
(mapcon #'list l))
计算表单(apply#'append(mapcon#'g'(12))
的结果是什么证明答案的正确性 我已经看到
mapcon
与ncoc
和cdr
一起工作,但最终的答案将是(12)
,我不知道如何正确解释它。请帮忙。首先,我们打电话:
(mapcon (lambda (list) (print list) nil) '(1 2))
由于匿名函数始终返回NIL,因此结果列表为NIL;调用打印以下内容:
(1 2)
(2)
因此,在您的示例中,当您调用(mapcon#'g'(12))
时,将首先使用(12)
调用g
,然后使用(2)
。函数g
返回一个列表,并将它们连接起来
通过显式计算每个部分,可以在REPL中复制发生的情况:
USER> (mapcon #'list '(1 2))
((1 2) (2))
USER> (mapcon #'list '(2))
((2))
USER> (nconc ** *)
((1 2) (2) (2))
最后,(应用#'附加列表)
调用带有参数列表的附加
append
的签名为:
append &rest lists => result
这意味着如果l1
、l2
和l3
是列表,则包含其所有元素的列表是:
(append l1 l2 l3)
这里,append
的参数存储在一个列表中,因此将任意参数列表传递给函数的方法是使用apply
。这意味着(apply#'append list)
连接列表中的所有列表,这就是为什么在您的例子中结果是(12)
请注意,当参数数量任意(可能较大)时,不建议使用apply
,因为apply
受CALL-arguments-LIMIT
的限制。另一种可能的方法是:
(loop for list in lists append list)
这里要理解的主要事情是
(mapcon #'f xs) = (apply #'nconc (maplist #'f xs))
= (loop for ys on xs nconc (f ys))
所以
(g xs) =
(mapcon #'list xs) = (apply #'nconc (maplist #'list xs))
= (loop for ys on xs nconc (list ys))
= (loop for ys on xs append (list ys))
= (loop for ys on xs collect ys )
;; = (maplist #'identity xs)
它只是将#'cdr
迭代应用于参数列表,收集其非空后缀:
[4]> (loop for ys on '(1 2) collect ys) ; (g '(1 2))
((1 2) (2))
[5]> (loop for ys on '( 2) collect ys) ; (g '( 2))
( (2))
因此,我们有
(mapcon #'g '(1 2))
=
(loop for ys on '(1 2) nconc (g ys))
=
(loop for ys in '((1 2) (2)) nconc (g ys)) ; ----- 'in' NB
=
(nconc (g '(1 2)) (g '(2)))
=
(append '((1 2) (2)) '((2)))
=
'( (1 2) (2) (2) )
因此
(apply #'append (mapcon #'g '(1 2)))
=
(apply #'append (nconc (g '(1 2)) (g '(2))))
=
(apply #'append (append '((1 2) (2)) '((2))))
=
(apply #'append '( (1 2) (2) (2) ))
=
( append '(1 2)'(2) '(2) )
=
'( 1 2 2 2 )