思考问题的方法不是下降到较低的实施水平,而是上升到我们可以思考什么scaled是的水平。问题不在于确定将n. 它正在弄清楚scaled应该做什么。
无论它做什么,它都需要返回一棵树。
; DefType F1 : Any -> Tree
(define (f1 x)
(leaf 42))
下一个最重要的事情是它需要将树作为输入。
; DefType F2 : Tree -> Tree
(define (f2 [t Tree?])
(leaf 42))
接下来必须解决输入和输出之间的同构问题。输出树的结构需要与输入树的结构相匹配。
; DefType F3 : Tree -> Tree
(define (f3 [t Tree?])
t)
从函数式编程的角度来看,这得到了我们想要的东西,但以牺牲质量为代价,因为f3返回的是对输入的引用,而不是从输入派生的值。该函数需要返回一个与输入值具有相同结构的新输出值。要复制结构,函数必须在传递 a 时返回 a node,在传递 a 时node返回leafa leaf。
; DefType F4 : Tree -> Tree
(define (f4 [t Tree?])
(type-case Tree t
[leaf (val) (leaf val)]
[node (val left right)
(node val (f4 left)(f4 right))]))
现在类型已经整理好,是时候处理将输入树转换为输出树了。这需要向上而不是向下移动。开始的地方是重写f4。
; DefType F5 : Tree -> Tree
(define (f5 [t Tree?])
(type-case Tree t
[leaf (val) (leaf (id val))]
[node (val left right)
(node (id val) (f5 left)(f5 right))]))
重要,但不是很有趣。用任意函数替换id似乎更有趣。太有趣了,可能值得添加第二个参数。
; DefType N2N : Number -> Number
; DefType F6 : Tree (Number -> Number) -> Tree
(define (f6 [t Tree?] [n2n N2N?])
(type-case Tree t
[leaf (val) (leaf (n2n val))]
[node (val left right)
(node (n2n val) (f6 left) (f6 right))]))
功能scaled:
; DefType Scaled : Tree Number -> Tree
(let ((f lambda(x y)(* x y)))
(define (scaled [t Tree?][n Number?])
(type-case Tree t
[leaf (val)(leaf (f n val))]
[node (val left right)
(node (f n val) (scaled left)(scaled right))])))