lisp - 使用以下规范在 LISP 中编写 Foo 函数

标签 lisp common-lisp

我正在努力寻找解决以下功能的正确方法

(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))))

所以我们有一个外部循环将 n0 递增到 (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/

相关文章:

list - 检查列表中是否有一定数量的元素

file-io - 在 Common Lisp 中处理并发文件访问

lisp - 将列表中的汽车评估为 lisp 中的函数

binding - LISP 负绑定(bind)

types - 任意类型说明符上的 Defmethod?

lisp - 如何在 quicklisp 中升级 asdf 版本?

recursion - lisp中的多级递归

lambda - 通过程序执行的说明

optimization - SBCL 优化 : function type declaration

macros - 从 Quicklisp 包内的宏调用函数