このブログ記事では、関数型プログラミング(Haskellを含む)において重要な概念であるカリー化の概念を紹介しています。

カリー化
カリー化は、関数型プログラミングの概念の一つで、多くの初心者が混乱しやすい概念です。カリー化は 関数をカレー味にすることではなく、複数の引数を持つ関数が、それぞれ1つの入力を持つ内包された関数として解釈されることを指します。
func:: a -> b -> c -> d
func:: a -> (b -> (c -> d))
この概念により、Haskellは一部のプログラマーには予想外の動作をすることがあります。簡単な例を見てみましょう。
add:: Int -> Int -> Int
add x y = x + y
上記の関数add
は、x
とy
を入力として受け取ります。しかし、次のように関数をリファクタリングすることができます。
add :: Int -> Int -> Int
add x = (\y -> x + y)
ここでは、関数はx
だけを入力として受け取りますが、y
は関数内に存在します。命令型プログラミング言語では、
これは受け入れがたいはずですが、Haskellでは関数が値として扱われるため、これは合法です。関数が関数を返すことは完全に許容されます。
add
関数の場合、上記の例は次に提供されるy
に対してx
を加える別の関数を返します。
add 1 --- Output: (\y -> 1 + y)
add 1 2 --- Output: 3
関数を少ない引数の関数に変換することを部分関数適用と呼び、関数型プログラミングでは広く利用されています。
実例
部分関数適用が実際にどのように使用されるかを見てみましょう。前の記事で取り上げたmap
関数が良い例です。正しく覚えていれば、map
関数は次のように適用できることがわかります。
map (\x -> x + 2) [1,2,3,4,5] --- Output: [3,4,5,6,7]
しかし、同じ匿名関数を複数回使用したい場合はどうでしょうか?(\x -> x + 2)を何度も入力する必要があるのでしょうか?幸いなことに、ここで部分関数適用を利用できます。
add2ToList = map (\x -> x + 2)
リストの要素に2を加える新しい関数が作成されました。この関数は何度でも再利用可能です。
クイズ
この記事では、学習した内容を確認するためのクイズを設けます。記事のメイン部分を読んだ後に、ぜひ自分で問題を解いてみることを強くお勧めします。各問題をクリックすると答えが表示されます。
リソース
- Philipp, Hagenlocher. 2020. Haskell for Imperative Programmers #7 - Partial Function Applications and Currying. YouTube.