まず、各手順を順番に見ていきましょうmember
。Schemeにはすでに標準member
関数があるので、同じ名前で新しいプロシージャを定義するのは悪い考えであることに注意してください。既存のmember
手順は次のとおりです。
member
にあるlstの最初の要素を見つけequal?
ますv
。そのような要素が存在する場合、その要素で始まるlstの末尾が返されます。それ以外の場合、結果は#f
です。
上記の手順はequal?
テストに使用し、期待とは異なる値を返します。意図した手順にやや近く、標準memq
機能があります。
memq
メンバーに似ていますが、eq?を使用して要素を検索します。
しかし、繰り返しになりますが、戻り値は期待したものではありません。を使用していることに注意して、このようにプロシージャを定義することをお勧めします。memq
規則に従って、名前は?
、これがブールプロシージャであることを示すためにで終わります。
(define (member? atm lst)
(if (memq atm lst) #t #f))
それでは、を見てみましょうduplicate-entries
。括弧の問題がいくつかあり(コードを正しくインデントするとこれが表示されます)、メンバーシッププロシージャの名前に問題があります(プロシージャは呼び出されmember
ますが、として呼び出していますmember?
)。member?
上記で定義したweを使用するか、を使用しますmemq
。この場合、両方のアプローチが正常に機能します。これmemq
は、要素が見つかった場合にfalse以外の値が返され、条件がtrueになるためです。
(define (duplicate-entries lst)
(cond ((null? lst) #f)
((member? (car lst) (cdr lst)) #t)
(else (duplicate-entries (cdr lst)))))
または、これが推奨される方法です。既存の手順で必要な処理が行われる場合は、車輪の再発明を行う必要はありません。
(define (duplicate-entries lst)
(cond ((null? lst) #f)
((memq (car lst) (cdr lst)) #t)
(else (duplicate-entries (cdr lst)))))