list - 从 lisp 中的列表中评估函数

标签 list function functional-programming lisp

我需要用 lisp 编写一个带有两个参数的函数——无参数函数列表和整数列表。 我需要按照第二个给定的顺序评估第一个列表中的函数,即 (fun '(#'a #'b #'c) '(2 0 1)) 应该评估 c、a、b。 我试过这样的功能:

(defun z4(funs kols)
    (funcall (nth (first kols) funs))
    (z4 funs (rest kols))
)

但是在函数调用中我得到了错误

NIL is not of type CONS.

这是什么意思?我通过简单地调用得到了同样的错误

(funcall (first funs))

所以我假设它与从函数列表中获取函数有关。如何评估从函数列表中获取的函数?

最佳答案

每次递归调用时,您都会减少 kols 参数,直到它变为 nil。当 kols 变为 nil 时,您应该终止递归,因此您应该添加终止条件(即空列表)的测试:

(defun foo (funcs order)
  (unless (endp order)
    (funcall (nth (first order) funcs))
    (foo funcs (rest order))))

我建议一个更具可读性的解决方案(它也更可取,因为 ANSI Common Lisp 标准不强制实现执行尾调用优化):

(defun foo (funcs order)
  (loop for n in order do (funcall (nth n funcs))))

在前面的示例中,我假设您运行函数是为了它们的副作用,而不是为了返回值。


编辑 1

正如 Vatine 指出的那样,使用 nth 和列表来提供随机访问的集合对性能不利,因此将函数存储在 vector 中可能是值得的(这是一个一维数组)而不是列表。因此,假设 funcs 是函数的 vector,函数可以定义如下:

(defun foo (funcs order)
  (loop for n in order do (funcall (aref funcs n))))

此外,如果函数数组是简单向量 ( glossary entry ),我们可以将aref 替换为svref。前者更通用,但后者在某些实现中可能更快。

可以使用任一方法创建函数的简单向量

(vector #'func-a #'func-b ...)

#(func-a func-b ...)

也可以使用 make-array 函数创建函数的简单向量,但前提是 :adjustable :fill-pointer 关键字参数未指定或 nil

关于list - 从 lisp 中的列表中评估函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14537372/

相关文章:

javascript - 为什么我的 Ramda 管道功能不能与过滤器一起使用?

python - 在 Python 中查找列表中的前 3 个最大值并将其位置保留在另一个列表中?

C# 指向列表<T> (WinForms)

function - 如何从不将 vec 作为参数的回调内部将值存储在 Vec 中?

python - 从函数中 exit() 是一种错误的形式吗?

scala - 如何在 Scala 中使用 Reader 和 Writer monad?

python - 从 2 个列表中相同索引位置删除多个元素

python - 使用python实现队列

c - 将结构体值从 function() 返回到 main()

list - 奥卡姆。返回列表的前 n 个元素