(wat-aro)

無職から有職者にランクアップしました

SICP 問題 2.6

(define zero (lambda (f) (lambda (x) x)))

(define (add-1 n)
  (lambda (f) (lambda (x) (f ((n f) x)))))

(add-1 zero)
(lambda (f) (lambda (x) (f (((lambda (f) (lambda (x) x)) f) x))))
(lambda (f) (lambda (x) (f ((lambda (x) x) x))))
(lambda (f) (lambda (x) (f x)))

(define one (lambda (f) (lambda (x) (f x))))

(add-1 one)
(lambda (f) (lambda (x) (f (((lambda (f) (lambda (x) (f x))) f) x))))
(lambda (f) (lambda (x) (f ((lambda (x) (f x)) x))))
(lambda (f) (lambda (x) (f (f x))))

(define two (lambda (f) (lambda (x) (f (f x)))))


(define (+ a b)
  (lambda (f) (lambda (x) ((a f) ((b f) x)))))
;; 始めにa,b両方にfを適用すると((lambda (f) ...) f)なので(f ... x))の形がそのまま残る.
;; この時前者は(lambda (x) (f ... x)) 後者も同じく(lambda (x) (f ... x))の形になる.
;; 後者にはxも適用すると(f ... x)だけになる.
;; これを前者に適用すれば(f ...x)のxが(f ... x)に置き換わるので(f ... (f ... x))の形になる.
;; zero や one の最初に(lambda (f) (lambda (x) ...))となっているので形を揃えて上記の手続きとなる.

(+ one two)
(lambda (f) (lambda (x) (((lambda (f) (lambda (x) (f x))) f) (((lambda (f) (lambda (x) (f (f x)))) f) x))))
(lambda (f) (lambda (x) ((lambda (x) (f x)) ((lambda (x) (f (f x))) x))))
(lambda (f) (lambda (x) ((lambda (x) (f x)) (f (f x)))))
(lambda (f) (lambda (x) (f (f (f x)))))