2008年11月3日月曜日

Haskell の部分適用 (2)

以前に Haskell で 部分適用 を試したとき、関数の第1引数から適用した。「Python で部分適用」 では、キーワード引数を利用することによってどの場所にある引数でも部分適用することができる。 Hakell でも同じように好きな場所の引数を部分適用するにはどうしたらいいのだろう?

例えば、引数を 3 つとる hoge 関数があるとする。

hoge a b c = a + b * c

普通に 3 つの引数に適用する場合、

  print $ hoge 5 6 7

この関数の第1引数のみ部分適用するなら、

hoge5 = hoge 5

これに引数を適用。

  print $ hoge5 6 7

 

flip , セクション

第2引数のみ部分適用する場合、Prelude の flip を利用できる。flip は、関数の第1引数と第2引数を逆順にする。例えば、flip を map に適用した場合の関数の型を調べると、

*Main> :t map
map :: (a -> b) -> [a] -> [b]
*Main> :t flip map
flip map :: [a] -> (a -> b) -> [b]

これを使い、

hoge6 = flip hoge 6

で、hoge 関数の第2引数のみ部分適用できる。

これに引数を適用。

  print $ hoge6 5 7

 

ところで、hoge の呼出しにおいて `関数` の形式を使うと、hoge の適用を以下のように書ける。

  print $ (5 `hoge` 6) 7

これを利用してセクションで、

hoge6' = (`hoge` 6)

これに引数を適用。

  print $ hoge6' 5 7

 

無名関数

では、第3引数のみを部分適用したいときはどうするのだろう?

例えば、新しく関数を定義するなら、

hoge7 a b = hoge a b 7

これに引数を適用。

  print $ hoge7 5 6

... のようにすればいいのかなと思ったら、FlexiblePartialApplication - Haskell Prime – Trac に無名関数を使ったシンプルな方法が書かれていた。

hoge7' = \a b -> hoge a b 7

あ~、なるほど。(@_@)

(via Search results for haskell partial application – MarkMail)