は ハ は は haskell


は は ハ ハ haskell - etc9からの続きです。

ラムダ式

まぁ、無名関数です はい。
引数を二乗する関数 square は以下のように定義できます。

square :: Num a => a -> a
square x = x * x

この関数には square という名前が付いていますが、名前を付けずに関数を定義できます。
それにはλ(実際にはバックスラッシュ 環境によっては\記号となる)を使い

\x -> x * x

のように定義します。

この関数には名前がありませんが、普通の関数と同じように利用できます。

(\x -> x * x)3

3 * 3 で結果は 9 となります。


以下のように x と y を与えると、その合計を返却する関数 add はラムダ式ではどのように表せるでしょうか。

add x y = x + y

haskell では add 関数は 引数にxを与えると、y を引数に取り、x + y を返却する関数 を返します。
これをラムダ式で表すと以下のようになります。

\x -> (\y -> x + y)

名前が無いので直接以下のように呼び出すと、

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

結果として 5 を得ることができます。


ラムダ式に名前を付けて、

add = (\x -> (\y -> x + y))

とすると、

add 2 3

のように通常の関数と同じように扱えます。


map関数

ラムダ式の典型的な利用方法として、map 関数の引数に利用するよね。
map の定義は以下となっており、

> :t map
map :: (a -> b) -> [a] -> [b]

aを与えるとbを返す関数 (a -> b) と、リスト[a]を引数として与えると、リスト[b]を返却します。
以下のようにラムダ式とリストを引数として与えると、各要素に2をかけたリストが返却されます。

> map (\x -> x * 2) [1..3]
[2,4,6]

セクション

数値 x と y の加算は演算子 + を使って、x + y と記載できます。
演算子を()で囲むと、x + y は以下のように書くことができます。

(+) x y

この括弧で括った演算子をセクションと呼びます。
数値 x と y がある場合に、セクションは以下のラムダ式と対応します。

(+)  = \x -> (\y -> x + y)
(x+) = \y -> x + y
(+y) = \x -> x + y


先ほどのmapの例の以下は、

> map (\x -> x * 2) [1..3]
[2,4,6]

セクションを使うと以下のように書くことができます。

map (* 2) [1..3]


セクションは、関数名をバッククオートで囲む、5 `div` 2 の逆パターン(演算子は括弧で括ると頭に出せる)です。


カリー化

カリー化とは、複数の引数をとる関数を、引数が「もとの関数の最初の引数」で戻り値が「もとの関数の残りの引数を取り結果を返す関数」であるような関数にすることです。
add 関数の 1 つの引数として 2 を拘束した add2 関数を定義できます。

add = (\x -> (\y -> x + y))
add2 = add 2

add2 関数は以下のように利用でき、

add2 3

結果として 3 を返却します。



つづく