LuX*_*orX 1 lisp functional-programming function common-lisp parameter-passing
我正在尝试创建一个接受列表和函数作为参数的函数,并将该函数应用于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)))
Run Code Online (Sandbox Code Playgroud)
这是第二次尝试:
(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)))
Run Code Online (Sandbox Code Playgroud)
但对于一些简单的混乱和无法解释的原因,我得到第一个错误:
#'FN should be lambda expression.
Run Code Online (Sandbox Code Playgroud)
这是第二个:
Undefined function R
Run Code Online (Sandbox Code Playgroud)
我尝试了很多东西但到目前为止还没有任何工作.
编辑::感谢您的帮助到目前为止.这个:
(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)))
Run Code Online (Sandbox Code Playgroud)
这应该做到这一点.但我仍然得到了
Undefined function FN
Run Code Online (Sandbox Code Playgroud)
错误.该怎么办???
sds*_*sds 10
filterremove-if-not
在Common Lisp中调用:
(remove-if-not #'evenp '(1 2 3 4 5))
==> (2 4)
Run Code Online (Sandbox Code Playgroud)
当您尝试调用存储在变量中的函数(或作为参数传递给函数)时,您需要使用funcall
或apply:
(mapcar (lambda (n) (funcall #'fn n)) L)
Run Code Online (Sandbox Code Playgroud)
或者只是传递给mapcar:
(mapcar fn L)
Run Code Online (Sandbox Code Playgroud)
这是一团糟.你需要学习Common Lisp语法,有很多好书(参见 想要学习常见的lisp).
具体问题是R在函数位置(第一个列表元素)但它没有被定义为函数 - 它是一个变量.即使您解决了这个问题,也存在更多问题.你应该读一本书,然后自己解决,这将是一个有用的练习.
基本上,在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))))
Run Code Online (Sandbox Code Playgroud)
这里有一个变量 fn,但是你正在使用它,就好像它是一个函数(#'fn).
你需要这样做
(remove-if-not fn '(1 2 3 4 5))
Run Code Online (Sandbox Code Playgroud)
代替.
print首先,print几乎
从来不是在代码中使用的正确功能.使用princ,prin1或
write改为.
其次,Common Lisp REPL 代表Read-Eval- Print Loop,因此您不需要显式打印函数的返回值.
您为其他人(包括您自己6个月后)编写代码以便阅读,而不仅仅是计算机运行.如果遵循约定,包括命名变量和函数,括号放置,缩进和c,则可以使代码更具可读性.
zerop写(zerop X)而不是(eq 0 X)(实际上,你应该使用eql数字,但现在变得太毛茸茸了).
length 可能很贵如果您需要知道的是否为空,请不要扫描整个列表.IOW,
(if (zero (length l))
(print "the list is empty")
(mapcar ... l))
Run Code Online (Sandbox Code Playgroud)
写得更好
(if (null l)
(print "the list is empty")
(mapcar ... l))
Run Code Online (Sandbox Code Playgroud)