我正在尝试编写一个函数来检查列表x中的每个元素是否都具有属性a,所以我写道:
(defun check (a x)
(if (listp x)
(eval (cons 'and (mapcar #'a x)))))
但它不起作用。 (基本上我希望a
成为函数的名称,比如说blablabla
,并且在check函数的主体中,#'a
我想表示函数blablabla
},而不是名为a
的函数。)现在上面的代码不起作用。我认为在Lisp中应该能够插入函数。我该如何解决?
(这是我在口齿不清的第一天,所以这可能是一个愚蠢的问题;) 和BTW我正在使用Lispworks 6.0个人版。)
答案 0 :(得分:6)
此处无需使用sharp-quote语法。其目的是在可变位置使用函数名称,但a
已经是变量。只需撰写a
而不是#'a
。
答案 1 :(得分:3)
您不需要eval
即可使用apply
。
问题所在:您需要funcall
,因为您提供了a
作为参数。 (编辑:不是这种情况。)引用你只需要参考函数a
而不是函数中的a。
(defun check (a xs)
(if (listp xs)
(every #'identity (mapcar a
xs))))
更好,请使用loop
:
(defun check (a xs)
(if (listp xs)
(loop for x in xs
always (funcall a x))))
最好,使用every
:
(defun check (a xs)
(if (listp xs)
(every a xs)))
答案 2 :(得分:2)
以下是我将如何编写类似于检查功能的内容。我试着给它一个更具描述性的名字。
(defun are-all-elements-fullfilling-fun-p (fun ls)
(every #'identity (mapcar fun ls)))
修改:请注意,更短更好的定义是
(defun are-all-elements-fullfilling-fun-p (fun ls)
(every fun ls)))
现在让我们说我们想用这个函数来调用它。请注意,我倾向于尽可能使用声明。如果编译器能够解决错误,我经常搞砸了一些事情并且调试很容易。代码也会运行得更快。
(defun is-even-p (n)
(declare (type number n))
(the boolean (= 0 (mod n 2))))
你必须把#'放在这里:
(are-all-elements-fullfilling-fun-p #'is-even-p '(1 2 3 4))
(are-all-elements-fullfilling-fun-p #'is-even-p '(38 2 4))