SICP 問題 2.45(right-split と up-split を、手続きを返す手続き split を使って具体化してみる)
問題
right-split と up-split は汎用分割演算の具体化として表すことができる。
(define right-split (split beside below)) (define up-split (split below beside))
の評価が既に定義したものと同じ振る舞いの手続き right-split と up-split を作り出すような性質を持つ手続き split を定義せよ。
解答
まずは二つを見比べてみよう。
(define (right-split painter n) (if (= n 0) painter (let ((smaller (right-split painter (- n 1)))) (beside painter (below smaller smaller))))) (define (up-split painter n) (if (= n 0) painter (let ((smaller (up-split painter (- n 1)))) (below painter (beside smaller smaller)))))
で、とりあえず共通するところを split に定義してみちゃう。
あ、split は手続きを返す手続きだから、一番外側は lambda 式になることに注意。
(define (split first second) (lambda (painter n) (if (= n 0) painter (let ((smaller ((split first second) painter (- n 1)))) (first painter (second smaller smaller))))
再帰呼び出しの箇所は、split を再帰的に呼び出して lambda 式を受け取り、その手続きに対して painter と n-1 を渡す感じ。