成员函数在cons结构中不起作用

时间:2012-10-11 13:54:45

标签: lisp common-lisp

我写了两个程序,一个是takeoutAllButLast,另一个是takeoutSecondLast。

我最初使用成员函数来确定是否有更多的X.

我尝试了一些数据并发现:

如果第一个参数是符号,它们都可以工作!

但如果是缺陷结构,它们都会失败。

1.// `(a b)   `((b b)(a b)(b c)(a b)) ==>  `((b b)(b c)(a b)) 

(defun takeoutAllButLast (X L)
(cond ((null L) nil)
       ((equal X (first L)) 
           (if (member X (rest L)) 
               (takeoutAllButLast X (rest L)) 
               L)) 
       (t (cons (first L) (takeoutAllButLast X (rest L))))
)
)

2.//`(a b)   `((a b)(b b)(a b)(b c)(a b)) ==>  `((a b)(b b)(b c)(a b)) 
(defun takeoutSecondLast (X L)
(cond ((null L) nil)
       ((equal X (first L)) 
           (if (member X (rest (member X (rest L))))
    (cons (first L) (takeoutSecondLast X (rest L)))
    (rest L)
           )
    )
   (t (cons (first L) (takeoutSecondLast X (rest L))))
 )

我想问的是如何确定是否还有一个元素是X,并且可以像成员函数一样使用?

为什么成员函数不能用于比较cons结构?

感谢您阅读我的问题!

1 个答案:

答案 0 :(得分:2)

member默认使用eql作为其等式谓词。这在符号,数字和其他一些事情上都很好((eq 'a 'a)始终为真,(let ((cons (cons 'a 'a))) (eql cons cons))始终为真,但(eql (cons 'a 'a) (cons 'a 'a))几乎从不为真。

您可以使用member关键字将另一个相等检查程序传递给:test,如果您使用#'equal,您将(可能)得到您想要的内容。

如果您想使用自定义相等检查器member致电foo,只需执行以下操作:

(member thing-to-check-for the-list-to-check :test #'foo)