2015/09/20

# プログラミングGauche ７.２練習問題

• for-each-numbersを書く
``````(define for-each-numbers
(lambda (proc lis)
(for-each proc (filter number? lis))))
``````
• map-numbersを書く
``````(define map-number
(lambda (proc lis)
(map proc (filter number? lis))))
``````
• numbers-onlyを書く
``````(define (numbers-only walker)
(lambda (proc lis)
(walker proc (filter number? lis))))
``````
• 「数値とそれ以外が混じっている入れ子のリスト」の数値だけについて`(numbers-only for-each)``(numbers-only map)``tree-walk`に渡して処理ができるか．できないならなぜできないか．

`tree-walk`のコードは以下の通り

``````(define (tree-walk walker proc tree)
(walker (lambda (elt)
(if (list? elt)
(tree-walk walker proc elt)
(proc elt)))
tree))
``````

``````(tree-walk (numbers-only map) print  '(1 2 (3 (#f 4))  (#t 5)))
``````

``````1
2
(#<undef> #<undef>)``````

``````(define (tree-walk walker proc tree)
(walker (lambda (elt)
(if (list? #?=elt)
(tree-walk walker proc elt)
(proc elt)))
tree))

(define (numbers-only walker)
(lambda (proc lis)
(walker proc #?=(filter number? lis))))

(tree-walk (numbers-only map) print  '(1 2 (3 (#f 4))  (#t 5)))
``````

``````#?="(standard input)":262:(filter number? lis)
#?-    (1 2)
#?=elt
#?-    1
1
#?=elt
#?-    2
2
(#<undef> #<undef>)``````

これを見ると`tree-walk`にリストが渡される前に`numbers-only``filter`が先に評価されている．
ここを改善して入れ子に対応した`filter`を書いて，`numbers-only-for-tree`を書く．
`(car lis)`がリストならそこに再帰して`filter`をかける．

``````(define filter-for-tree
(lambda (pred lis)
(cond
((null? lis) '())
((list? (car lis)) (cons (filter-for-tree pred (car lis))
(filter-for-tree pred (cdr lis))))
((pred (car lis)) (cons (car lis)
(filter-for-tree pred (cdr lis))))
(else (filter pred (cdr lis))))))

(define (numbers-only-for-tree walker)
(lambda (proc lis)
(walker proc (filter-for-tree number? lis))))
``````

`numbers-only`と同じように実行してみます．

``````gosh> (tree-walk (numbers-only-for-tree map) print  '(1 2 (3 (#f 4))  (#t 5)))
1
2
3
4
5
(#<undef> #<undef> (#<undef> (#<undef>)) (#<undef>))``````