Home Diary 倉庫

2004年3月19日

2004年3月19日

Church数

SICPの最初のほうに、listが手続きで表現できる例がのっている。(問題2.4)


(define (my-cons x y)
  (lambda (m) (m x y)))

(define (my-car z)
  (z (lambda (p q) p)))

(define (my-cdr z)
  (z (lambda (p q) q)))

(display (my-car (my-cons 10 20)))
(display "\n")
(display (my-cdr (my-cons 30 40)))
(display "\n")


mizuy@chalk% gosh list-p.sc
10
40

アレゲ。同様に数も手続で実装できる。これをChurch数というんだそうな。(Church Numeral)


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

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

(define (int-of n)
  ((n (lambda (x) (+ x 1))) 0))

(display (int-of zero))
(newline)
(display (int-of (add-1 zero)))
(newline)


(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))))))
(define four
  (lambda (f) (lambda (x) (f (f (f (f x)))))))

(display (int-of one))
(newline)
(display (int-of four))
(newline)


mizuy@chalk% gosh church.sc
0
1
1
4

要は、数が、「fを引数にとって「xを引数にとり、xにfをその数分だけ作用させるlambda」を返すlambda」として表現されている。そんなわけで負の数を表現するにはやっかい。掛けたり足したりする演算は簡単にかける。


zero            = \f x -> x
one             = \f x -> f x
two             = \f x -> f (f x)
three           = \f x -> f (f (f x))
four            = \f x -> f (f (f (f x)))

inc n           = n+1
intof n         = n inc 0

haskell. haskellには無限リストがある。


zero            = \f x -> x

inc             = (+ 1)
intof n         = n inc 0
addone n        = \f x -> f (n f x)

cadd p q        = \f x -> (q f (p f x))

church_i n      = n : church_i (addone n)
church          = church_i zero


Main> map intof (take 10 church)
[0,1,2,3,4,5,6,7,8,9]
Main> map intof (map (cadd (addone zero)) (take 10 church))
[1,2,3,4,5,6,7,8,9,10]
Main> map intof (map (cadd (addone (addone zero))) (take 10 church))
[2,3,4,5,6,7,8,9,10,11]

haskell書くの初めてだけどこんなんでいいんかなぁ...schemeよりは読みやすい。lambda抽象とか読み易い。schemaは目がちらちらして...

物理部夏合宿

8/2-8/6 at新潟

暇ならいく。この時期って暇なんだっけ?大学て。

後期受験料13000円返還

前期うかっても後期足切りでももどってくる。4000円はどこへいったのやら。東工大とかないらしいから返ってくるだけましだけど。

SD(4)

やねうらおのD言語記事発見。で、この表紙の女の絵は一体...

cvs,svn

triaezにsvnがはいってないからサイトをsvnとCVSの両方の管理下においたディレクトリ用意しといて、svnのworking copyで編集、commit、両管理下のworking copyでsvn update、cvs commit、triaez上でcvs update。CVSでは.svn/をignore、svnではCVS/をignore

差分のみuploadするにはこれしか。