应用从函数列表中选择的函数

Apply a selected function from a list of functions

我想从函数列表中select。并将选择的函数应用于参数。

 (defvar fn '(#'(lambda (x) (* x x)) #'(lambda (x) (+ x x))))
 (apply (nth 1 fn) '(5))

以上代码无法运行可能是哪里出了问题?

fn 不是函数列表。由于您引用了该列表,因此计算了 none 个函数表达式。因此,您只有 (FUNCTION (LAMBDA (X) ...)).

形式的列表列表

使用list制作列表并评估所有参数:

(defvar fn (list #'(lambda (x) (* x x)) #'(lambda (x) (+ x x))))

或者使用反引号和逗号:

(defvar fn `(,#'(lambda (x) (* x x)) ,#'(lambda (x) (+ x x))))

如果您使用 Lisp,可以交互式地探索这些数据结构:

CL-USER 50 > '(#'(lambda (x) (* x x)) #'(lambda (x) (+ x x)))
((FUNCTION (LAMBDA (X) (* X X)))
 (FUNCTION (LAMBDA (X) (+ X X))))

以上是列表。元素是什么类型:

CL-USER 51 > (mapcar #'type-of *)
(CONS CONS)

上面说元素不是函数,而是cons cells

我们现在评估列表元素:

CL-USER 52 > (mapcar #'eval **)
(#<anonymous interpreted function 40600010FC>
 #<anonymous interpreted function 406000112C>)

这些元素是什么类型的?现在它们是函数:

CL-USER 53 > (mapcar #'type-of *)
(FUNCTION FUNCTION)

'(#'(lambda (x) (* x x)) #'(lambda (x) (+ x x)))) 是一个带引号的表达式。 fn 是您示例中的符号列表。

你实际上希望 lambdas 被评估为 functions 所以你会删除引号并写:

(defvar *fn* (list (lambda (x) (* x x)) (lambda (x) (+ x x))))

现在每个 function 对象确实可以用作 apply 的参数:

(apply (car *fn*) (list 3))
=> 9 

funcall 也存在。通过阅读 HyperSpec,看看您是否可以理解它与 apply 的区别。你可以这样称呼它:

(funcall (cadr *fn*) 3)
=> 6