SICP 問題 2.28(葉をトップレベルの要素に全て展開する)

【問題】

引数として(リストとして表現されている)木をとり、その要素が、木の全ての葉を、左から右の順に並べたものであるリストを返す手続き fringe を書け。例えば、

(define x (list (list 1 2) (list 3 4)))
(fringe x)
(1 2 3 4)
(fringe x x)
(1 2 3 4 1 2 3 4)

【解答】

これも再帰使う感じ。

(define (fringe . lis)
  (reverse (let loop  ((src lis)
		       (dst '()))
	     (cond ((null? src) dst)
		   ((list? (car src))
		    ;処理対象要素がリストだった場合は、
		    ;リストだった要素を改めてloopして処理してやる必要がある。
		    (loop (cdr src) (loop (car src) dst)))
		   (else
		    (loop (cdr src) (cons (car src) dst)))))))

ソース中のコメントでも記述したけど、気をつけるべきは枝に対して改めてloopの再帰処理をしてやる必要があること。
それから、一通りの再帰処理ででてきた結果は逆順になってるので最後にreverseを実行してやることぐらい。
では実験。


gosh> (fringe x)
(1 2 3 4)
gosh> (fringe x x)
(1 2 3 4 1 2 3 4)
gosh> (fringe x x x)
(1 2 3 4 1 2 3 4 1 2 3 4)
gosh>
おっけ〜。