gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-03 18:55:49 26 4
gpt4 key购买 nike

我需要用 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com