カリー化

カリー化とは



カリー化(currying)とは、複数の引数を取る関数を、一つの引数を持つ関数に変換するプロセスを指します。この技法は、特に関数型プログラミングの文脈で重要な概念であり、論理学者ハスケル・カリーの名前に由来しています。実際には、カリー化の考案者としてはモーゼス・ショーンフィンケルやゴットロープ・フレーゲがクレジットされています。

カリー化の基本概念



カリー化を理解するためのシンプルな例として、関数 f(a, b) = c を考えます。この関数 f は二つの引数 a と b を取り、結果 c を返します。カリー化された関数 F(a) は、最初の引数 a を受け取り、その後 g(b) を呼び出すことで最終的な結果 c を返す関数となります。この場合、g は b を引数として受け取り、最終的に c を生成するサブルーチンです。

一般的に、関数 f の形式は f: (X × Y) → Z と表現され、これをカリー化した関数 g は g: X → (Y → Z) という形になります。つまり、g は最初の引数を受け取った後、次に二つ目の引数を受け取る関数を返すわけです。

カリー化の応用



カリー化は計算機科学の理論において重要な役割を果たしています。複数の引数を持つ関数を一つの引数を持つ複数の関数に分離することで、単純になった理論的モデルでの研究が可能になります。また、圏論ではカリー化の概念がデカルト閉圏における冪対象の普遍性と関連付けられています。この関連は特定の対象間の射(マップ)を一意に対応させることにより、新たな理論的洞察を提供します。

部分適用の容易さも、カリー化の重要な利点の一つです。たとえば、加算関数をカリー化して、最初の引数に 1 を適用することで簡単にインクリメント関数を作成することが可能です。

カリー化を基盤とするプログラミング言語



カリー化を取り入れたプログラミング言語もあります。特に、MLやHaskellでは関数は常に一つの引数を取る形式を持ち、複数の引数を持つ関数は基本的にネストした一引数関数の構文の糖衣構文として扱われます。また、LISP、Scheme、F#、ScalaErlangEiffelPerlRubyPythonR言語S言語JavaScript、Swiftなど、第一級関数を扱える言語でもカリー化関数の作成が可能です。

カリー化の実装例



例えば、除算を行う関数 div(x, y) = x / y をカリー化した関数を cdiv(x) とすると、この cdiv 関数は引数 x のみを受け取ります。その後、inv = cdiv(1) とすると、inv は y のみを引数に取る関数となり、inv(y) = 1 / y という計算を行います。このように、カリー化を利用することで新たな関数を簡単に生成することができます。

カリー化と部分適用の違い



カリー化と部分適用は混同されがちですが、これらは異なる操作です。部分適用とは、複数の引数を持つ関数に対して一部の引数に具体的な値を適用する操作を指します。たとえば、先述の div(x, y) から inv(y) を生成する場合がこれにあたります。一方、カリー化は引数への具体的な適用を行わず、代わりに新しい関数を生成することが主な目的です。カリー化が行う変換は、関数の形を変えるものであり、実引数を適用する段階までは進まない点に注意が必要です。

タプル引数との関連



Haskellでは、標準関数 curry がカリー化とは厳密には異なる動作をすることもあります。この関数は、二つの要素からなるタプルを引数に取る一引数関数を、二つの引数を持つ関数に変換します。Haskellの全ての関数は本来一つの引数を持つものとして扱われており、厳密にはカリー化を行う関数を定義することは難しいですが、理論的には二つの要素を持つタプルの型を直積とみなすことで、相互に理解できる部分があります。

まとめ



カリー化は、関数プログラミングにおいて極めて重要な概念であり、関数をより柔軟かつ使いやすくする手段を提供します。この技術を理解することで、効率的なプログラムを書くための新たな視点を得ることができるでしょう。

もう一度検索

【記事の利用について】

タイトルと記事文章は、記事のあるページにリンクを張っていただければ、無料で利用できます。
※画像は、利用できませんのでご注意ください。

【リンクついて】

リンクフリーです。