【问题标题】:working with lisp functions使用 lisp 函数
【发布时间】:2012-10-21 08:47:49
【问题描述】:
我正在尝试编写一个返回列表中原子列表的函数,假设我有一个列表,其中包含原子和列表,当我运行该函数时,它应该返回内部原子列表。 .
例如:
(func '(2 34 5 (12) 7 (A B C) +))
-> (2 34 7 +)
我想试试结果中的参数是否为真,这样当我运行时:
(ATOM ( (func '(2 34 5 (12) 7 (A B C) +)) )
->T
关于我如何去做的任何想法?书籍或参考资料?
【问题讨论】:
标签:
functional-programming
lisp
common-lisp
【解决方案1】:
使用标准 CL 函数,
[3]> (remove-if-not #'atom '(1 2 (12) +))
(1 2 +)
[6]> (every #'atom (remove-if-not #'atom '(1 2 (12) +)))
T
如果你想自己写,你可以把#'atom 融合进去,做两个专门的函数,比如remove-atoms 和every-is-atom。但是“原子”是built-in function atom 的名称。
第一种写法是
(defun remove-atoms (xs &aux (ys (list 1)))
(let ((p ys))
(dolist (x xs (cdr ys))
(if (atom x) (setf (cdr p) (list x) p (cdr p))))))
这使用破坏性更新以自上而下的方式构建结果列表,这并不违反函数式编程的精神here,因为它是在本地使用的,作为一种实现技术。这可以看作是来自其他答案的通用功能tail-recursive-modulo-cons 代码的特定于 Common-LISP 的翻译。
还有第二个功能:
(defun every-is-atom (xs)
(dolist (x xs T)
(if (not (atom x))
(return-from every-is-atom NIL))))
【解决方案2】:
所以你想要一个只返回作为参数传递的列表中存在的原子值的函数?
像这样?
(defun func (lst)
(cond
((null lst) '())
((atom (first lst))
(cons (first lst) (func (rest lst))))
(t (func (rest lst)))))
不适用于 Common lisp,但在我看来仍然是一本好书:SICP