0

私は2つのプログラムを書いています。1つは takeoutAllButLast で、もう1つは takeoutSecondLast です。

最初にメンバー関数を使用して、背後に X があるかどうかを判断します。

そして、いくつかのデータを試してみると、次のことがわかりました。

最初の引数がシンボルの場合、どちらも機能します!

しかし、cons 構造の場合、どちらも失敗します。

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 の背後にまだ 1 つの要素があり、メンバー関数のように使用できるかどうかを判断する方法です。

また、メンバー関数を使用してコンス構造を比較できないのはなぜですか?

私の質問を読んでくれてありがとう!

4

1 に答える 1

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)
于 2012-10-11T14:34:40.390 に答える