プログラミングGauche 7.2 手続きを取る手続き 練習問題
2009年05月05日
プログラミングGaucheの練習問題(p68)を解く。
for-each-numbers
(define (for-each-numbers proc lis) (for-each proc (filter number? lis))) (for-each-numbers print '(1 2 #f 3 4 #t)) gosh> 1 2 3 4 #<undef>
map-numbers
(define (map-numbers proc lis) (map proc (filter number? lis))) (map-numbers (lambda (x) (* x 2)) '(1 2 #f 3 4 #t)) gosh> (2 4 6 8)
numbers-only
(define (numbers-only walker) (lambda (proc lis) (walker proc (filter number? lis)))) ((numbers-only for-each) print '(1 2 #f 3 4 #t)) gosh> 1 2 3 4 #<undef> ((numbers-only map) (lambda (x) (* x 2)) '(1 2 #f 3 4 #t)) gosh> (2 4 6 8)
numbers-only を tree-walk に渡すと、ネストされたリストをたどっていかないために目的を達成できない。
(tree-walk (numbers-only for-each) print '((1 2 #t 3 #f) 4 5 #t #f (6 (7 8 #f)))) gosh> 4 5 #<undef>
手続き filter
はフラットなリストにのみ作用するために、ネストされたリストが扱えない。
(filter number? '((1 2 #t 3 #f) 4 5 #t #f (6 (7 8 #f)))) ;gosh> (4 5)
walker
はリストの各要素に手続きを作用させなければならない。
そこで、入れ子のリストに対して作用する filter-for-tree
を作る。
(define (filter-for-tree pred lis) (cond ((null? lis) '()) ((pair? (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-for-tree pred (cdr lis))))) (filter-for-tree number? '((1 2 #t 3 #f) 4 5 #t #f (6 (7 8 #f)))) gosh> ((1 2 3) 4 5 (6 (7 8)))
filter-for-tree
を使って、入れ子になったリストに作用する numbers-only-for-tree
を作る。
(define (numbers-only-for-tree walker) (lambda (proc lis) (walker proc (filter-for-tree number? lis)))) (tree-walk (numbers-only-for-tree for-each) print '((1 2 #t 3 #f) 4 5 #t #f (6 (7 8 #f)))) gosh> 1 2 3 4 5 6 7 8 #<undef> (tree-walk (numbers-only-for-tree map) (lambda (x) (* x 2)) '((1 2 #t 3 #f) 4 5 #t #f (6 (7 8 #f)))) gosh> ((2 4 6) 8 10 (12 (14 16)))
プログラミングGauche
posted with amazlet at 08.11.14
Kahuaプロジェクト
オライリージャパン
売り上げランキング: 22775
オライリージャパン
売り上げランキング: 22775