この章ではネストしたリストを再帰する手法を学ぶ。
rember*
アトム a
とリスト l
を引数にとり、l
に含まれる a
と等しい要素をすべて取り除く関数 rember*
を定義する。ここで、 l
は入れ子になったリストの可能性がある。
rember*.scm
(define rember*
(lambda (a l)
(cond
((null? l) (quote ()))
((atom? (car l))
(cond
((eq? (car l) a)
(rember* a (cdr l)))
(else (cons (car l)
(rember* a (cdr l))))))
(else (cons (rember* a (car l))
(rember* a (cdr l)))))))
(define a 'cup)
(define l '((coffee) cup ((tea) cup) (and (hick)) cup))
(print (rember* a l))
出力は ((coffee) ((tea)) (and (hick)))
。
occur*
occur*
はリスト l
とアトム a
を引数にとり、l
に含まれる a
と等しい要素の個数を計算する関数である。ここで、 l
は入れ子になったリストの可能性がある。
occur*.scm
(define occur*
(lambda (a l)
(cond
((null? l) 0)
((atom? (car l))
(cond
((eq? (car l) a)
(add1 (occur* a (cdr l))))
(else (occur* a (cdr l)))))
(else (o+ (occur* a (car l))
(occur* a (cdr l)))))))
(define a 'cup)
(define l '((coffee) cup ((tea) cup) (and (hick)) cup))
(print (occur* a l))
member*
同じ要領で、リストに特定の要素が含まれるか調べる関数を定義する。
member*.scm
(define member*
(lambda (a l)
(cond
((null? l) #f)
((atom? (car l))
(or (eq? (car l) a)
(member* a (cdr l))))
(else (or (member* a (car l))
(member* a (cdr l)))))))
srember
S式のリスト l
から任意のS式 s
を取り除いたS式のリストを返す関数を定義する。
srember.scm
(define srember
(lambda (s l)
(cond
((null? l) quote())
((equal? (car l) s) (cdr l))
(else (cons (car l)
(srember s (cdr l)))))))
(define s 'cup)
(define l '((coffee) cup ((tea) cup) (and (hick)) cup))
(print (srember s l))
出力は ((coffee) ((tea) cup) (and (hick)) cup)
感想
そろそろ注意深く読んでいかないとハマりそうな予感。