我正在编写一个带有列表的程序,并用“X”替换所有元素(无论是原子,缺点还是列表)。所以,如果我用以下方式评估我的功能:
((A B) (C . D) E))
它将返回
((X X) (X . X) X))
但是,在尝试评估我的功能时,我不断收到“X不是预期的类型LIST”错误。但我不明白为什么。我在Windows下使用Allegro Common Lisp Express版。我究竟做错了什么?
(defun exify (lst)
(exify-aux lst nil))
(defun exify-aux (lst acc)
(if (null lst)
acc
(if (atom (car lst))
(append 'x acc)
(if (consp (car lst))
(append (cons 'x 'x) acc)
(if (listp (car lst))
(append (exify-aux (car lst) nil) acc)
(if (eq (car lst) nil)
(append nil acc))))))
(exify-aux (cdr lst) acc))
答案 0 :(得分:2)
(append 'x acc)
该怎么办?附加清单。 x
是一个符号。
另外,(append nil acc)
的目的是什么?附加空列表没有任何用处。 (append '() '() '() '())
只是()
。
答案 1 :(得分:2)
你的代码中有很多死代码,而且它是一个无限循环。
(defun exify-aux (lst acc)
;; This whole block if, correct, doesn't amount to any result
(if (null lst)
acc
(if (atom (car lst))
(append 'x acc)
(if (consp (car lst))
(append (cons 'x 'x) acc)
(if (listp (car lst))
(append (exify-aux (car lst) nil) acc)
(if (eq (car lst) nil)
(append nil acc))))))
;; This is the tail call and it's called unconditionally
(exify-aux (cdr lst) acc))
您需要与cons
更亲密。
(defun exify (tree)
(cond ((null tree) nil)
((atom tree) 'x)
(t (cons (exify (car tree))
(exify (cdr tree))))))
当你在那里时,你可能想要做更高阶的功能:
(defun exify (tree)
(accumulate-tree tree
(lambda (_) 'x) ; replaces all non nil leafs with x
#'cons ; copies branches
nil)) ; copies empty leafs
accumualte-tree可以这样定义:
(defun accumulate-tree (tree term combiner null-value)
(labels ((rec (tree)
(cond ((null tree) null-value)
((atom tree) (funcall term tree))
(t (funcall combiner (rec (car tree))
(rec (cdr tree)))))))
(rec tree)))