チャーチ数の簡単な計算(Ruby)
Wikipedia の OCaml の項目を読んでいたら、OCaml ではチャーチ数の計算がきれいに書けることを知った。
let zero f x = x let succ n f x = f (n f x) let one = succ zero let two = succ (succ zero) let add n1 n2 f x = n1 f (n2 f x) let to_int n = n (fun k -> k+1) 0 let _ = print (add (succ two) two)
ほう、さすがである。
では我が Ruby では似たようなことは可能であるのか。OCaml ほど簡潔ではないが、可能である。『アンダースタンディング・コンピュテーション』という名著を参考に書いてみる。
$ pry [1] pry(main)> zero = -> f { -> x { x } } => #<Proc:0x000055918b649bb0@(pry):1 (lambda)> [2] pry(main)> def to_integer(n) n.(-> k { k + 1 }).(0) end => :to_integer [4] pry(main)> to_integer(zero) => 0 [5] pry(main)> succ = -> n {-> f {-> x { f.(n.(f).(x)) } } } => #<Proc:0x000055918b3654f8@(pry):5 (lambda)> [6] pry(main)> one = succ.(zero) => #<Proc:0x000055918b7143b0@(pry):5 (lambda)> [7] pry(main)> to_integer(one) => 1 [8] pry(main)> two = succ.(one) => #<Proc:0x000055918b7653a0@(pry):5 (lambda)> [9] pry(main)> to_integer(two) => 2 [10] pry(main)> add = -> m {-> n { n.(succ).(m) } } => #<Proc:0x000055918b7b8528@(pry):10 (lambda)> [11] pry(main)> to_integer(add.(succ.(two)).(two)) => 5
うーむ、これが 3 + 2 か…。
アンダースタンディング コンピュテーション ―単純な機械から不可能なプログラムまで
- 作者: Tom Stuart,笹田耕一,笹井崇司
- 出版社/メーカー: オライリージャパン
- 発売日: 2014/09/18
- メディア: 大型本
- この商品を含むブログ (11件) を見る