SICPの勉強 問題2.4~6
2.4
cons, car, cdrをclosureを使って作成:
(defn cons [x y] (fn [m] (m x y))) (defn car [z] (z (fn [p q] p))) (defn cdr [z] (z (fn [p q] q)))
2.5
自然数に限定してcons, car, cdrを2と3の積を使って表す。
(defn cons [x y] (loop [x x y y r 1] (cond (pos? x) (recur (dec x) y (* 2 r)) (pos? y) (recur x (dec y) (* 3 r)) :else r))) (defn car [z] (loop [z z r 0] (if (zero? (rem z 2)) (recur (/ z 2) (inc r)) r))) (defn cdr [z] (loop [z z r 0] (if (zero? (rem z 3)) (recur (/ z 3) (inc r)) r)))
題意的にremを使っていいのかが微妙だが・・・
2.6
自然数を関数で表す。(Church数の実装)
まずは問題で定義されているzeroとadd-1をclojureで定義し直す:
(def zero (fn [f] (fn [x] x))) (defn add-1 [n] (fn [f] (fn [x] (f ((n f) x)))))
それを踏まえて、one、two、そしてaddがどのようになるか、直接定義してみる:
(def one (fn [f] (fn [x] (f x)))) (def two (fn [f] (fn [x] (f (f x))))) (def add [a b] (fn [f] (fn [x] ((a f) ((b f) x)))))
fを何回重ねて適用するか、で数字を表している。