チャーチ数の続き2

C++ での実装がよくわからなくなってきたので,勉強するとして
とりあえず,関数型で書いてみた.

#!/usr/bin/env escript

main(_) ->
    Zero = fun(_) -> (fun(X) -> X end) end,
    One = add_1(Zero),
    Two = add_1(One),
    io:format("zero = ~p~n", [display_church(Zero)]),
    io:format("one = ~p~n", [display_church(One)]),
    io:format("two = ~p~n", [display_church(Two)]),
    io:format("(2 + 1) + 2 = ~p~n", [display_church(plus(add_1(Two), Two))]).

add_1(N) ->
    fun(F) ->
            fun(X) ->
                    F((N(F))(X))
            end
    end.

plus(M, N) ->
    fun(F) ->
            fun(X) ->
                    (M(F))((N(F))(X))
            end
    end.

display_church(N) ->
    Inc = fun(X) -> X + 1 end,
    (N(Inc))(0).
#!/usr/bin/env runghc

main = do let zero = \f -> \x -> x
              one = add_1 zero
              two = add_1 one
          putStrLn $ "zero = " ++ (show $ display_church zero)
          putStrLn $ "one = "  ++ (show $ display_church one)
          putStrLn $ "two = "  ++ (show $ display_church two)
          putStrLn $ "(2 + 1) + 2 = " ++
                       (show $ display_church $ plus (add_1 two) two)

add_1 n = \f -> \x -> f $ (n f) x
plus m n = \f -> \x -> (m f) $ (n f) x
display_church n = let inc = \x -> x + 1
                   in n inc 0
#!/usr/bin/env ocaml

let zero = fun f -> (fun x -> x);;

let add_1 n =
  fun f ->
    fun x ->
      f ((n f) x);;

let one = add_1 zero;;
let two = add_1 one;;

let plus m n =
  fun f ->
    fun x ->
      ((m f) ((n f) x));;

let display_church n = 
  let inc x = x + 1
  in n inc 0;;


Printf.printf "zero = %d\n" (display_church zero);;
Printf.printf "one = %d\n" (display_church one);;
Printf.printf "two = %d\n" (display_church two);;
Printf.printf "(2 + 1) + 2 = %d\n" (display_church (plus (add_1 two) two));;
  • Erlang は,最初全部 fun で書いていて 10行くらいで書いていたけど,あまりにも読めなそうなので,改行したりした.
    • fun だよね.function とかlambda とか長過ぎ
  • Haskell が短いのが楽しい
    • ラムダがバックスラッシュ一文字で書けるのも楽で良いですね
  • OCaml は,慣れてなさ過ぎですね.サーセン

もう一回くらいエントリ書けるかも.