もしRubyistがHaskellを学んだら(19) ラムダ式と畳み込み
タグ: learning_haskell / 初版公開: 2014-01-14

とうとう出てきましたよラムダ式。関数型言語では良く目にして、初学者の心を折るC言語でいうポインタのようなものである。

ラムダ式とはいわゆる無名関数で、その名の通り名前のない関数を作ることができる。例えば、与えられた引数をそのまま返すラムダ式は(\x -> x)で、以下のように書ける。GHCiでさくっと実行してみよう。

Prelude> (\x -> x) 1
1

では2引数を取り、それを加算して返すラムダ式はどうだろうか。これは(\x y -> x + y)で、やはりGHCiで実行させると期待どおりに動作する。

Prelude> (\x y -> x + y) 1 2
3

ここまではつまらないが、リストを畳み込むfoldlfoldrと組み合わせると、一気にラムダ式が強力なものに思えてくる。foldlの型は以下のとおり。

Prelude> :t foldl
foldl :: (a -> b -> a) -> a -> [b] -> a

2引数をとる関数と、アキュムレータ(初期値のようなもの)、リストを受け取りアキュムレータと同じ型の値を返す。foldlはリストを走査して、関数を適用してアキュムレータを更新しつつ、最後にアキュムレータを返す動作をする。

先ほどのつまらないラムダ式をfoldlに与えて、リストの要素を合計するsum'を定義してみることにする。foldlで畳み込みを行うので、明示的に再帰を使っていないのがポイントだ。

  • sum’.hs
sum` :: (Num a) [a] -> a
sum' xs = foldl (\x y -> x + y) 0 [xs]

GHCiからロードして実行させてみる。

Prelude> :l sum'.hs
[1 of 1] Compiling Main             ( sum'.hs, interpreted )
Ok, modules loaded: Main.
*Main> sum' [1, 2, 3]
6

他に畳み込みに使える関数としては、リストを右から評価するfoldr、リストの先頭の値をアキュムレータとするfoldr1foldr1、アキュムレータの中間状態をリスト化するscanlscanrなどがある。

ラムダ関数と畳み込みについては”すごいHaskellたのしく学ぼう!”の5.4と5.5が詳しい。

すごいHaskellたのしく学ぼう!
Miran Lipovača
オーム社
売り上げランキング: 126,678