チャーチ数の続き

せっかくインストールしたので,IronPython スクリプトを書いてみよう.

#!ipy

def make_zero():
    def _(f):
        def _(x):
            return x
        return _
    return _

def add_1(n):
    def _(f):
        def _(x):
            return f(n(f)(x))
        return _
    return _

def plus(m, n):
    def _(f):
        def _(x):
            return m(f)(n(f)(x))
        return _
    return _

def display_church(n):
    def inc(x):
        return x + 1
    return n(inc)(0)

zero = make_zero()
one = add_1(zero)
two = add_1(one)

print("zero = %s" % display_church(zero))
print("one = %s" % display_church(one))
print("two = %s" % display_church(two))
print("((2 + 1) + 2) = %s" % display_church(plus(add_1(two), two)))

ついでにRuby でも書いてみた.
lambda と書けます.

#!/usr/bin/env ruby

zero = lambda {|f|
  lambda {|x|
    x
  }
}

def add_1(n)
  lambda {|f|
    lambda {|x|
      f.call(n.call(f).call(x))
    }
  }
end

def plus(m, n)
  lambda {|f|
    lambda {|x|
      m.call(f).call(n.call(f).call(x))
    }
  }
end

def display_church(n)
  n.call(lambda {|x| x + 1}).call(0)
end

one = add_1(zero)
two = add_1(one)

puts "zero = #{display_church(zero)}"
puts "one = #{display_church(one)}"
puts "two = #{display_church(two)}"
puts "((2 + 1) + 2) = #{display_church(plus(add_1(two), two))}"

Python は,return が必須みたい.無いとNone を返す.
最初関数名を _f, _x とかにしていたんだけど,
nested-scope だから大丈夫かな.ということで,全部 _ にしてみた.
一応,Python 3.0 でも動く筈.

Ruby は,call がウザい気がしたんだけど,
メソッドチェーンが意外に気持いいことがわかった.