Abstract your answer to exercise 2.30 to produce a procedure
tree-map with the property that square-tree could be defined as
(define (square-tree tree) (tree-map square tree))To do this, let's look at the two
map-based procedures, scale-tree and square-tree:
(define (scale-tree tree factor)
(map (lambda (sub-tree)
(if (pair? sub-tree)
(scale-tree sub-tree factor)
(* sub-tree factor)))
tree))
(define (square-tree tree)
(map (lambda (sub-tree)
(if (pair? sub-tree)
(square-tree sub-tree)
(square sub-tree)))
tree))
They're pretty similar. Sure, scale-tree takes an extra parameter, and they apply different operations when a non-pair element is being mapped, but the general pattern is the same. I.e.:
(define (doSomethingToA-tree tree possiblyWithSomeParameters)
(map (lambda (sub-tree)
(if (pair? sub-tree)
(doSomethingToA sub-tree possiblyWithSomeParameters)
(applyOperationTo sub-tree possiblyWithSomeParameters)))
tree))
If we encapsulate the operation to apply to non-pair elements and the optional parameters into a procedure then we'd be able to generalize this process as follows:
(define (tree-map proc tree)
(map (lambda (sub-tree)
(if (pair? sub-tree)
(tree-map proc sub-tree)
(proc sub-tree)))
tree))
Then we can define both scale-tree and square-tree in terms of tree-map:
(define (scale-tree tree factor) (tree-map (lambda (x) (* x factor)) tree)) (define (square-tree tree) (tree-map square tree))And then put them to the test:
> (scale-tree (list 1 (list 2 (list 3 4) 5) (list 6 7))
10)
'(10 (20 (30 40) 50) (60 70))
> (scale-tree (list 1
2
(list 3 (list 4 5) 6)
(list 7 (list 8 (list 9)) 10 (list 11))
(list 12))
2)
'(2 4 (6 (8 10) 12) (14 (16 (18)) 20 (22)) (24))
> (square-tree
(list 1
(list 2 (list 3 4) 5)
(list 6 7)))
'(1 (4 (9 16) 25) (36 49))
> (square-tree
(list 1
2
(list 3 (list 4 5) 6)
(list 7 (list 8 (list 9)) 10 (list 11))
(list 12)))
'(1 4 (9 (16 25) 36) (49 (64 (81)) 100 (121)) (144))
No comments:
Post a Comment