SICPの勉強 問題1.30
SICP1.3.1の問題1.30を解いてみる。
末尾再帰にするのがポイント。問いの中のコードをできるだけ利用するなら:
(defn sum [f a next b] (letfn [(iter [a result] (if (> a b) result (recur (next a) (+ (f a) result))))] (iter a 0)))
これで先ほどの(integral cube 0 1 0.0001)
を試すとStackOverflowを起こさずに正常に計算する。
ただ、clojureなら関数内関数を定義するよりloop/recurのほうが自然:
(defn sum [f a next b] (loop [a a result 0] (if (> a b) result (recur (next a) (+ (f a) result)))))
さらにClojure的に書くなら:
(defn sum [f a next b] (->> (iterate next a) (take-while #(<= % b)) (map f) (apply +)))