計算機プログラムの構造と解釈 第二版 P34 問題1.32
やばい、思ったより簡単だった。
もちろん、間違ってるかもだけど。
これは、前に出てきてるsumとproductをさらに、accumulateという関数で
抽象化できませんか?という問題。
抽象化をどうやって考えるかといえば、
ざっくり、今まで固定値だった部分を、パラメータにしてやればいい。
んで、sumとproductの例で考えると、
sumからproductを作ったときには、「+」を「*」にしました。
sumからproductを作ったときには、終了の判定のあと返す値を「0」から「1」にしました。
と考えると、この二つをパラメータにして渡してやれば抽象化できそう。
与えられている式が
(accumulate combiner null-value term a next b)
となっていて、sumの時は
(sum term a next b)
だったから、
「term」 「a」 「next」 「b」はこのままでいいとして、
あとは、
sumの時、「*」になっていたところを「combiner」に
sumの時、「0」だったところを「null-value」に変えてやればいい
のではないかな?
あとは再帰的なのも、反復的なのも考え方はいっしょ!!
もうそこはほとんど問題にならぬ!!
そしてさらっとやってみた結果がこれだ!!
例として、1から10までの足し算と、5の階乗の計算をやってみた。
#!/usr/local/bin/gosh ;; -*- coding: utf-8 -*- (use ggc.debug.trace) (use math.mt-random) (define (inc x) (+ 1 x)) (define (donothing x) x) ;;再帰的プロセス (define (accumulate combiner null-value term a next b) (if (> a b) null-value (combiner (term a) (accumulate combiner null-value term (next a) next b)))) ;;反復的プロセス (define (accumulate-r combiner null-value term a next b) (define (iter a result) (if (> a b) result (iter (next a) (combiner result (term a))))) (iter a null-value)) ;; main (define (main args) (display "sum (ex. add 1 to 5) made by accumulate : ") (display (accumulate + 0 donothing 0 inc 10))(newline) (display "product (ex. 5!) made by accumulate : ") (display (accumulate * 1 donothing 1 inc 5))(newline)(newline) (display "sum (ex. add 1 to 5) made by accumulate-r : ") (display (accumulate-r + 0 donothing 0 inc 10))(newline) (display "product (ex. 5!) made by accumulate-r : ") (display (accumulate-r * 1 donothing 1 inc 5))(newline) )
実行
sum (ex. add 1 to 5) made by accumulate : 55 product (ex. 5!) made by accumulate : 120 sum (ex. add 1 to 5) made by accumulate-r : 55 product (ex. 5!) made by accumulate-r : 120
さらっとできたので、むしろちょっと不安です。