SICP 問題 2.6(数字を使わずに数字を表現する)
【問題】
対を手続きで表現することがそれほどの驚きでなければ、手続きを操作できる言語では、0 と、1 を足す演算を、
(define zero (lambda (f) (lambda (x) x))) (define (add-1 n) (lambda (f) (lambda (x) (f ((n f) x)))))
と実装することで、(少なくとも非負の整数を問題にする限りは)数を使わないで済ませることが出来ることを考えよう。
この表現は発明者 Alonzo Church(λ算法を発明した論理学者)に従い、Church数(Church numerals)として知られている。
(zero と add-1 を使わずに)one と two を直接定義せよ。(ヒント:(add-1 zero) を評価するのに、置き換えを使おう。)(add-1 の繰り返し作用させず)加算手続き + を直接定義せよ
【解答】
どこから手をつけていいのやらさっぱり。。ヒントが出ているのでありがたく使わせて頂こう。
というわけで、(add-1 zero) の置き換えをしてみる。
(add-1 zero) ;↓ (add-1 (lambda (f) (lambda (x) x))) ;↓ (lambda (f) (lambda (x) (f (((lambda (f) (lambda (x) x)) f) x)))) ;↓ (lambda (f) (lambda (x) (f x)))
あ〜、(add-1 zero) はつまり「1」を意味するから、この結果がつまり1であると?そういうことなのか?
(define one (lambda (f) (lambda (x) (f x))))
じゃ、次は two だ。
(add-1 (lambda (f) (lambda (x) (f x)))) ;↓ (lambda (f) (lambda (x) (f (((lambda (f) (lambda (x) (f x))) f) x)))) ;↓ (lambda (f) (lambda (x) (f (f x))))
というわけで、two の定義は、
(define two (lambda (f) (lambda (x) (f (f x)))))
threeとか、どんどん f が増えていく感じなんかね?あってんのかなぁ。。