Haskellでラムダ計算をやってみたいと思います。
転職のため某社の面談で「関数型言語をやっていますが、大丈夫ですか」と言われた。もともとオブジェクト指向言語の素晴らしさに気づいて、pythonをやり続けていたが、関数型にも興味があった。調べてみると、Haskellというのがあるらしい。少し続けていくと、なんか昔興味を持っていたChurchのラムダ計算に似ていることに気づいた。これは運命のめぐりあわせかもしれないと思い、Haskellを学び始めた。そこでラムダ計算をHaskellでできないかと挑戦してみた。
参考にしたのは以下の記事:
二乗する関数はラムダ記法では以下のようになる。
$$\lambda x.x^2$$関数を二重に適用する操作は$$\lambda x.f(f(x)$$となり、関数$f$も盛り込んで書くと、$$\lambda f.\lambda x.f(f(x))$$となる。
この2つの関数を合成して変数に$5$を与えると、$$((\lambda f.\lambda x.f(f(x)))(\lambda y.y^2))(5)$$
となります。
これをHaskellで表現すると以下のようになった。
ghci> doublef f x = f (f x)
ghci> square y = y * y
ghci> main = (doublef square) (5)
ghci> main
625
5を二乗したもの$5*5=25$に二乗を適用して、$25^2=625$となりきちんと計算されているね。
演習1
$$(((\lambda f.\lambda x.f(f(f(x))))(\lambda g.\lambda y.g(g(y))))(\lambda z.z+1))(0)$$
三重の関数適用、二重の関数適用、1増加の3つの関数が組み合わさったものです。Haskellで書くと、
-- exercise1.hs
triplef f x = f (f (f x))
doublef g y = g (g y)
add1 x = x + 1
main = do
print $ ((triplef doublef) add1) (0)
ghci> :load exercise1
[1 of 2] Compiling Main ( exercise1.hs, interpreted )
Ok, one module loaded.
ghci> main
8
あれ?なぜ8になるのかな?
誰か理由が分かったら教えてください。
Haskellの本はこれを買いました。