Решение упражнения 2.45 из SICP

4 February, 2008 (20:56) | Решения упражнений

У процедур right-split и up-split есть очень много общего. По сути, они отличаются лишь порядком вызова операций beside и below. Таким образом мы можем ввести обобщенную операцию generic-split, которая будет задавать схему работы, общую для right-split и up-split, и процедуру высшего порядка split, которая с помощью generic-split по заданным операциям (главной и вложенной) будет генерировать конкретную процедуру, реализующую определенный способ рекурсивного комбинирования рисовалок по этой обобщенной схеме.

Сказанное иллюстрирует приведенное ниже определение процедуры split:

(define (split main-operation sub-operation) 
  (define (generic-split painter n) 
    (if (= n 0) 
        painter 
        (let ((smaller (generic-split painter (- n 1)))) 
          (main-operation painter (sub-operation smaller smaller))))) 
  generic-split)

Еще раз подчеркну, что split – это операция высшего порядка, принимающая на вход и дающая на выходе операции над рисовалками. Она принимает на вход две комбинирующие операции над рисовалками и возвращает также операцию над рисовалками.

Это дает возможность определять конкретные операции над рисовалкми таким образом:

(define right-split (split beside below))
(define up-split (split below beside))

Comments

Comment from Максим
Date: December 2, 2014, 10:08 pm

Выразил своё решение через список:

(define (split op1 op2)
(define (enumerate-painters low high)
(if (> low high)
null
(cons painter
(enumerate-painters (+ low 1) high))))
(lambda (painter n)
(accumulate (lambda (x y) (op1 x (op 2 y y)))
painter
(enumerate-painters 1 n))))

Comment from Oleg
Date: December 12, 2014, 11:04 pm

Максим, интересное решение. Только (define (enumerate-painters…)) нужно поместить внутрь lambda

Write a comment