我正在尝试创建一个接受列表和函数作为参数的函数,并将该函数应用于List中的每个元素。 这是我的尝试:
(defun filter(fn L)
(if (eq 0 (length L))
(print "list empty")
(print (mapcar (lambda (n) (#'fn n)) L))))
(print (filter #'evenp '(1 2 2 3 4)))
这是第二次尝试:
(defvar R nil)
(defun filter(fn L)
(if (eq 0 (length L))
nil
(cons (R (funcall fn (car L)) filter(fn (cdr L))))))
(print(filter #'evenp '(1 2 2 3 4)))
但是对于一些令人困惑和无法解释的原因, 我得到了第一个错误:
#'FN should be lambda expression.
这是第二个:
Undefined function R
我已经尝试了很多东西,但到目前为止还没有任何工作。
编辑:: 谢谢你的帮助到目前为止。这样:
(defun filter(fn L)
(if (eq 0 (length L))
(print "list empty")
(remove-if-not #'fn '(1 2 3 4 5))))
(print (filter #'evenp '(1 2 2 3 4)))
这应该这样做。但我还是得到了
Undefined function FN
错误。怎么办???
答案 0 :(得分:10)
filter
被称为remove-if-not
在Common Lisp中:
(remove-if-not #'evenp '(1 2 3 4 5))
==> (2 4)
当您尝试调用存储在变量中的函数(或传递给
作为参数的功能),你需要
使用funcall
或apply
:
(mapcar (lambda (n) (funcall #'fn n)) L)
或者只是传递它
到mapcar
:
(mapcar fn L)
这是一团糟。 你需要学习Common Lisp语法,有很多好书(见 want to learn common lisp)。
具体问题是R
处于功能位置(第一个列表
element)但它没有定义为函数 - 它是一个变量。
即使您解决了这个问题,也存在更多问题。
你应该读一本书然后自己解决,这将是一本书
有用的运动。
基本上,在Common Lisp中,括号是有意义的。
例如,在C中你可以写x+y
,(x+y)
,(x)+(y)
& c,它们都意味着
相同。
在Common Lisp中R
,(R)
,((R))
& c非常不同。
(defun filter(fn L)
(if (eq 0 (length L))
(print "list empty")
(remove-if-not #'fn '(1 2 3 4 5))))
这里有变量 fn
,但您正在使用它,好像它是函数(#'fn
)。
你需要做
(remove-if-not fn '(1 2 3 4 5))
代替。
print
首先,print
是虚拟的
从不在代码中使用正确的函数。使用princ
,prin1
或
而是write
。
第二,Common Lisp REPL 代表Read-Eval- 打印 循环,因此您无需打印 明确返回函数的值。
您可以为其他人(包括您自己6个月后)编写代码,而不仅仅是让计算机运行。 如果遵循约定,包括命名变量和函数, 括号放置,缩进& c,使代码更具可读性。
zerop
写(zerop X)
代替(eq 0 X)
(实际上,你应该
使用eql
表示数字,但这是
现在变得太毛茸茸了。)
length
可能很贵如果您需要知道的是否是,请不要扫描整个列表 空。 IOW,
(if (zero (length l))
(print "the list is empty")
(mapcar ... l))
最好写成
(if (null l)
(print "the list is empty")
(mapcar ... l))
答案 1 :(得分:2)
#'FN应该是lambda表达式。
您的代码中有(fn(cdr L)),而 fn 无法像这样调用。就像之前的那一行一样,你需要做(过滤器fn(cdr L)),而不是过滤器(fn(cdr L))。
未定义的函数R
这里也是一样的。你有(cons(R ...)),你试图将 R 称为函数,但事实并非如此。对于我用 R 尝试做什么并不是很清楚,所以我无法在那里提供任何帮助。