とうとう出てきましたよラムダ式。関数型言語では良く目にして、初学者の心を折るC言語でいうポインタのようなものである。
ラムダ式とはいわゆる無名関数で、その名の通り名前のない関数を作ることができる。例えば、与えられた引数をそのまま返すラムダ式は(\x -> x)
で、以下のように書ける。GHCiでさくっと実行してみよう。
Prelude> (\x -> x) 1
1
では2引数を取り、それを加算して返すラムダ式はどうだろうか。これは(\x y -> x + y)
で、やはりGHCiで実行させると期待どおりに動作する。
Prelude> (\x y -> x + y) 1 2
3
ここまではつまらないが、リストを畳み込むfoldl
やfoldr
と組み合わせると、一気にラムダ式が強力なものに思えてくる。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
、リストの先頭の値をアキュムレータとするfoldr1
とfoldr1
、アキュムレータの中間状態をリスト化するscanl
とscanr
などがある。
ラムダ関数と畳み込みについては”すごいHaskellたのしく学ぼう!”の5.4と5.5が詳しい。
すごいHaskellたのしく学ぼう!
posted with amazlet at 14.01.09
Miran Lipovača
オーム社
売り上げランキング: 126,678
オーム社
売り上げランキング: 126,678