SICP 問題 2.30(mapの拡張)

【問題】

問題 2.21 の square-list 手続きと類似の手続き square-tree を定義せよ。
つまり、square-tree は、次のように振る舞わなければならない。


(square-tree
(list 1
(list 2 (list 3 4) 5)
(list 6 7)))
(1 (4 (9 16) 25) (35 49))
square-tree を直接(つまり高階手続きを使わずに)、また map と再帰を使って定義せよ。


【解答】

トップレベルだけでなく枝の先まで手続きを適用するようにしてやればいいと。
まずは高階関数を使わないバージョン。

;高階関数を使わないバージョン
(define (square-tree tree)
  (let loop ((sub tree)
	     (dst '()))
    (cond ((null? sub)
	   (reverse dst))
	  ((list? (car sub))
	   (loop (cdr sub) (cons (loop (car sub) '()) dst)))
	  (else
	   (loop (cdr sub) (cons (expt (car sub) 2) dst))))))

では実験。


gosh> (square-tree '(1 (2 (3 4) 5) (6 7)))
(1 (4 (9 16) 25) (36 49))
gosh>
よしよし。つぎ、mapと再帰を使用したバージョン。

;mapを使用するバージョン
(define (square-tree tree)
  ;2乗を求める手続き
  (define (square x)
    (* x x))
  ;受け取った要素を判別して適切な処理を行う。
  (define (square-map x)
    (if (list? x)
	(square-tree x)
	(square x)))
  ;実処理
  (map square-map tree))

では実験。


gosh> (square-tree '(1 (2 (3 4) 5) (6 7)))
(1 (4 (9 16) 25) (36 49))
gosh>
おっけ〜。