我正在努力寻找解决以下功能的正确方法
(FOO #'– '(1 2 3 4 5))
=> ((–1 2 3 4 5) (1 –2 3 4 5) (1 2 –3 4 5) (1 2 3 –4 5) (1 2 3 4 –5))
foo 函数的第一个参数应该是一个函数“-”,它必须应用于返回列表列表的每个元素,如上所示。我不确定我可以采用什么方法来创建此功能。我想到了递归,但不确定如何在每次调用中保留列表以及我会有什么样的基本标准。任何帮助,将不胜感激。我不能使用循环,因为这是函数式编程。
最佳答案
很遗憾你不能使用 loop
因为这可以像这样优雅地解决:
(defun foo (fctn lst)
(loop
for n from 0 below (length lst) ; outer
collect (loop
for elt in lst ; inner
for i from 0
collect (if (= i n) (funcall fctn elt) elt))))
所以我们有一个外部循环将 n
从 0
递增到 (length lst)
排除,以及一个内部循环将逐字复制列表,但应用 fctn
的元素 n
除外:
CL-USER> (foo #'- '(1 2 3 4 5))
((-1 2 3 4 5) (1 -2 3 4 5) (1 2 -3 4 5) (1 2 3 -4 5) (1 2 3 4 -5))
用递归代替loop
是指用labels
来代替内循环和外循环来创建局部函数,例如:
(defun foo (fctn lst)
(let ((len (length lst)))
(labels
((inner (lst n &optional (i 0))
(unless (= i len)
(cons (if (= i n) (funcall fctn (car lst)) (car lst))
(inner (cdr lst) n (1+ i)))))
(outer (&optional (i 0))
(unless (= i len)
(cons (inner lst i) (outer (1+ i))))))
(outer))))
关于lisp - 使用以下规范在 LISP 中编写 Foo 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36238929/