第10回SICP勉強会

内容

  • データ抽象の続き
    • こちらはそんなに

問題

問題2.6
;; 問題2.6

;; zeroとadd-1を使わずにoneとtwoを実装
;; add-1を繰り返さずに+を定義する

;; 0の定義
(define zero (lambda (f) (lambda (x) x)))
;; 引数として手続きfをとり、
;; 引数としてxをとりxを返す手続きを返す

;; 1をたす演算
(define (add-1 n)
  (lambda (f) (lambda (x) (f ((n f) x)))))
;; 引数として手続きnをとる
;; 引数として

;; http://www23.atwiki.jp/selflearn/pages/16.html#id_e78ae615
;; http://blog.livedoor.jp/dankogai/archives/50458503.html
;; http://d.hatena.ne.jp/tsz/20090110/1231604057
;; 要は、ある数は、ある関数fを何回xに適用するか、という定義にしてしまうのである。
(define one (lambda (f) (lambda (x) (f x))))
(define two (lambda (f) (lambda (x) (f (f x)))))
(define three (lambda (f) (lambda (x) (f (f (f x))))))

;; 1を加えるという処理を複数回繰り返して0,1を実現
;; 数値として見えるようにincrement処理をする引数を与えてみる
((one (lambda(x) (+ x 1))) 0)
((two (lambda(x) (+ x 1))) 0)


;; 足し算
;; fをb回適用した後に、fをa回適用する
;; fをb回適用した値に、fをa回適用することで実現
(define (add a b)
  (lambda (f)
    (lambda (x)
      ((a f) ((b f) x)))))

(((add one two) (lambda (x) (+ x 1))) 0)
;; gosh> 3

(((add one one) (lambda (x) (+ x 1))) 0)
;; gosh> 2

(((add two two) (lambda (x) (+ x 1))) 0)
;; gosh> 4



;; べき乗
;; bにaを
(define (exp a b)
  (b a))

(((exp two three) (lambda (x) (+ x 1))) 0)
;; 2**3
;; gosh> 8

(((exp tree three) (lambda (x) (+ x 1))) 0)
;; 3**3
;; gosh> 27


;; 掛け算
;; fをb回適用させた手続きにa回適用させる
;; ↑でb*aを実現
(define (mul a b)
  (lambda (f)
    (lambda (x)
      ((a (b f)) x))))

(((mul two two) (lambda (x) (+ x 1))) 0)
;; 2 * 2
;; gosh> 4

(((mul two three) (lambda (x) (+ x 1))) 0)
;; 2 * 3 ;; gosh> 6
問題2.7
;; 問題2.7
;; 区間の抽象化の実装

;; 2.1.4で定義した演算
(define (add-interval x y)
  (make-interval (+ (lower-bound x) (lower-bound y))
                 (+ (upper-bound x) (upper-bound y))))

(define (mul-interval x y)
  (let ((p1 (* (lower-bound x) (lower-bound y)))
        (p2 (* (lower-bound x) (upper-bound y)))
        (p3 (* (upper-bound x) (lower-bound y)))
        (p4 (* (upper-bound x) (upper-bound y))))
    (make-interval (min p1 p2 p3 p4)
                   (max p1 p2 p3 p4))))

(define (div-interval x y)
  (mul-interval x 
                (make-interval (/ 1.0 (upper-bound y))
                               (/ 1.0 (lower-bound y)))))

;; 区間構成子
(define (make-interval a b) (cons a b))

;; 選択子upper-bound, lower-boundの実装
(define (upper-bound x) (car x))
(define (lower-bound x) (cdr x))


;; 試してみる
(define R1 (make-interval 7.48 6.12))
(define R2 (make-interval 4.735 4.205))

(upper-bound R1)
;; gosh> 7.48
(lower-bound R1)
;; gosh> 6.12

(add-interval R1 R2)
;; gosh> (10.325 . 12.215)
(mul-interval R1 R2)
;; gosh> (25.7346 . 35.41780000000001)
(div-interval R1 R2) ;; gosh> (1.2925026399155226 . 1.7788347205707493)
問題2.8
;; 問題2.8
;; 二つの区間の差の計算

;; x > yとした時
;; x-yのupper-bound : xのupper-bound - yのlower-bound
;; x-yのlower-bound : xのlower-bound - yのupper-bound
(define (sub-interval x y)
  (make-interval (- (upper-bound x) (lower-bound y))
                 (- (lower-bound x) (upper-bound y))))

(define R1 (make-interval 7.48 6.12))
(define R2 (make-interval 4.735 4.205))

(sub-interval R1 R2) ;; gosh> (3.2750000000000004 . 1.3849999999999998)
問題2.9
;; 問題2-9

http://csnagoya-sicp.g.hatena.ne.jp/clairvy/20090411/sicp_ex_2_9
↑がなかなか詳しい 展開していって、幅だけで表現できないことを示している

所感

  • church数で頭がこんがらがった