insertL-f と insertR-f
rember を rember-f に変形したように、insertL を insertL-f に変形してください、ときた。といってもすぐに答が書いてあるので、ここは逆らわずに写経。
(define insertL-f (lambda (test?) (lambda (new old l) (cond ((null? l) (quote ())) ((test? (car l) old) (cons new (cons old (cdr l)))) (else (cons (car l) ((insertL-f test?) new old (cdr l))))))))
同様に、insertR を insertR-f に。
(define insertR-f (lambda (test?) (lambda (new old l) (cond ((null? l) (quote ())) ((test? (car l) old) (cons old (cons new (cdr l)))) (else (cons (car l) ((insertR-f test?) new old (cdr l))))))))
見比べればわかるように、insertL-f と insertR-f はよく似ている。実際、関数名を別にすれば違うのは6行目の new を old を cons する順番だけだ。
というわけで、次の課題はこの部分を関数として渡してやれるようにすることだ。
insert-g
まずは、上の6行目の部分だけを行う関数、seqL と seqR を書こう。といってもほとんど自明だ。
(define seqL (lambda (new old l) (cons new (cons old l)))) (define seqR (lambda (new old l) (cons old (cons new l))))
さあ、これで insert-g が書ける。全体を示そう。
(define insert-g (lambda (test? seq) (lambda (new old l) (cond ((null? l) (quote ())) ((test? (car l) old) (seq new old (cdr l))) (else (cons (car l) ((insert-g test? seq) new old (cdr l)))))))) (define seqL (lambda (new old l) (cons new (cons old l)))) (define seqR (lambda (new old l) (cons old (cons new l)))) (define insertL (insert-g eq? seqL)) (define insertR (insert-g eq? seqR)) (print (insertL 'topping 'fudge '(ice cream with fudge for dessert))) (print (insertR 'jalapeno 'and '(tacos tamales and salsa)))
実行結果:
^o^ > gosh insert-g.scm (ice cream with topping fudge for dessert) (tacos tamales and jalapeno salsa)
うまくいった!
と思って答を見たら、こんな定義になってるじゃないか。
(define insert-g (lambda (seq) (lambda (new old l) (cond ((null? l) (quote ())) ((eq? (car l) old) (seq new old (cdr l))) (else (cons (car l) ((insert-g seq) new old (cdr l))))))))
test? はどこへいったんだよ!
まあいい、このままいこう。最後に、seqL を使わずに insertL を定義してください、ときた。前のエントリで書いたように、lambda で作った関数には必ずしも名前をつけなくてもかまわない。ということは、seqL という関数名じゃなくてその定義を渡してやればいいわけだ。
(define insert-g (lambda (test? seq) (lambda (new old l) (cond ((null? l) (quote ())) ((test? (car l) old) (seq new old (cdr l))) (else (cons (car l) ((insert-g test? seq) new old (cdr l)))))))) (define insertL (insert-g eq? (lambda (new old l) (cons new (cons old l))))) (print (insertL 'topping 'fudge '(ice cream with fudge for dessert)))
^o^ > gosh insert-g2.scm (ice cream with topping fudge for dessert)
OKのようだ。よかった。