从 up-split
和 right-split
中抽取出一个通用的 split
抽象:
;;; 45-split.scm
(define (split big-combiner small-combiner)
(lambda (painter n)
(if (= n 0)
painter
(let ((smaller ((split big-combiner small-combiner) painter (- n 1))))
(big-combiner painter
(small-combiner smaller smaller))))))
前面的 split
函数,因为缺少一种引用自身的手段,所以 let
部分的代码非常长,一种缩短代码的办法是使用一个辅助函数:
;;; 45-another.scm
(define (split big-combiner small-combiner)
(define (inner painter n)
(if (= n 0)
painter
(let ((smaller (inner painter (- n 1))))
(big-combiner painter
(small-combiner smaller smaller)))))
inner)
新的 split
避免了过长的 let
表达式,但仍然有一个不太美观的地方:它在最后需要返回 inner
函数。
;;; 45-up-split.scm
(load "45-split.scm")
(define up-split (split below beside))
;;; 45-right-split.scm
(load "45-split.scm")
(define right-split (split beside below))