练习 2.45

up-splitright-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 函数。

使用 split 重定义 up-split

;;; 45-up-split.scm

(load "45-split.scm")

(define up-split (split below  beside))

使用 split 重定义 up-split

;;; 45-right-split.scm

(load "45-split.scm")

(define right-split (split beside below))

讨论

blog comments powered by Disqus