同値かどうかの判定に q? eqv? equal? のうちどれを使えば良いか分からなかったのでGauche ユーザリファレンス 6.1 等価を参考にテストしてみた。
(define (list-for-each pred dat ls) (call/cc (lambda (return) (for-each (lambda (x) (if (pred x dat) (return x))) ls) "not found"))) (define test '((abc)(1 2 ("def")) "hello" 999 hijk 0.123)) (define dat1 (car (cdr test))) ; メモリ上の同じオブジェクト (define dat2 'hijk) (define dat3 999) (define dat4 0.123) (define dat5 "hello") (define dat6 '(1 2 ("def"))) (print (list-for-each eq? dat1 test)) ;=> (1 2 (def)) (print (list-for-each eq? dat2 test)) ;=> hijk (print (list-for-each eq? dat3 test)) ;=> 999 (print (list-for-each eq? dat4 test)) ;=> not found (print (list-for-each eq? dat5 test)) ;=> not found (print (list-for-each eq? dat6 test)) ;=> not found (print (list-for-each eqv? dat1 test)) ;=> (1 2 (def)) (print (list-for-each eqv? dat2 test)) ;=> hijk (print (list-for-each eqv? dat3 test)) ;=> 999 (print (list-for-each eqv? dat4 test)) ;=> 0.123 (print (list-for-each eqv? dat5 test)) ;=> not found (print (list-for-each eqv? dat6 test)) ;=> not found (print (list-for-each equal? dat1 test)) ;=> (1 2 (def)) (print (list-for-each equal? dat2 test)) ;=> hijk (print (list-for-each equal? dat3 test)) ;=> 999 (print (list-for-each equal? dat4 test)) ;=> 0.123 (print (list-for-each equal? dat5 test)) ;=> hello (print (list-for-each equal? dat6 test)) ;=> (1 2 (def))
eq? eqv? equal? の使い分けについて検索すると「Schemeへの道/述語」があった。
eq?,eqv?,equal?では,等しいと判定される判断基準が異なる. * eq?は,比較する2つの引数がシステム内部で同一のデータ(セル)を指し示している場合に#tを返す. * eqv?は,eq?で等しいか数値として等しい2つの引数が与えられたとき#tを返す. * equal?は,評価した結果が等しいような2つの引数が与えられたとき#tを返す. * eq?で等しいと判定されるデータは,eqv?,equal?でも等しい. * eqv?で等しいと判定されるデータは,equal?でも等しい. * equal?で等しいと判定されるデータがeqv?,eq?で等しいとは限らない. * eqv?で等しいと判定されるデータがeq?で等しいとは限らない. * equal?は汎用的.eq?は高速. 直観的には, * symbolの比較には,eq? * symbolと数値を同時に扱う場合は,eqv?(数値のみを扱う場合は,"="の方がよい) * listの構造の比較には,equal? を使う.