プログラミング Gauche 練習問題を解く[7.2]

引き続き読み進めております。「手続きを取る手続き」というなかなか楽しい章に突入しました。しかし、頭の中を整理しつつ例題、練習問題と向き合っていると中々進みませんね。まだまだ頭が固い。本章での重要項目は「手続きは手続きを引数とする事が出来る」、「手続きは手続きを返す事ができる」の2点です。前者はC言語であれば、引数に関数ポインタを取る関数といったイメージですが、後者はLisp系独特では無いかと思います。しかし、lambdaはPythonなどにもあったのでお馴染みの方にはお馴染みです。

色々と苦戦しつつ練習問題を解きました。とりあえず以下が自分の解答。



1、数字とそれ以外のモノが混ざっているリストを受け取り、数値にだけについて手続きを適用するfor-each-numbersを書け

(define (for-each-numbers proc ls)
; リストが空でないかどうか
(if (null? ls)
#f
;filter で数値のみのリストを返してもらう
(filter (lambda (a) (if (number? a) (proc a) #f)) ls)
)
)
数値だけに手続きを適用し、結果をリストにするmap-numbersを書け

(define (map-numbers proc ls)
; リストが空でないかどうか
(if (null? ls)
ls
;filter で数値のみのリストを返してもらう
(proc (filter (lambda (a) (if (number? a) a #f)) ls))
)
)
数値だけに手続きを適用し、その結果をリストにするmap-numbersを書け

(define (numbers-only walker)
; 手続きを返す
(lambda (proc ls)
(if (null? ls)
; リストが空であれば何もしない
#f
; 数値である要素に手続きを適用する
(walker proc (filter (lambda (a) (if (number? a) a #f)) ls))
)))
とりあえずそれっぽい結果が返ってきます。で、回答例を見てみますと。

;; 数値とそれ以外のものが混ざっているリストを受け取り、その中の数値だけについて
;; 手続きを適用する手続きfor-each-numbersを書いてみてください。

(define (for-each-numbers proc lis)
(for-each proc (filter number? lis)))

;; 数値だけに手続きを適用してその結果をリストにするmap-numbersも
;; 書いてみましょう。

(define (map-numbers proc lis)
(map proc (filter number? lis)))

;; for-eachやmap等の手続きを受け取り、それを数値だけに適用する手続きへと
;; 変換するnumbers-onlyを書いてみましょう。

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

となにやら最初の2問を難しく考えすぎたというか、意味をはき違えて解答してしまいました…。というより、lambdaを使う事を意識しすぎて変なコードになっている気があります。いかんです。思い込みは。さて、最後にもう一問あるんですが、じつはまだ取り込み中です。まだまだ頭の中がLisp脳になっておらず1問1問に手こずっていまして。この試行錯誤している過程が楽しい!プログラムは止められんw