数学やコンピュータサイエンスにおいて、カリー化(ハスケル・カリーにちなんで名付けられた)とは、複数の引数を取る関数を、それぞれが単一の引数を取る関数の集合に変換する手法である。
典型的な例では、関数から始めます。これは 2 つの引数を取ります。1 つはそして1つはそしてオブジェクトを生成するこの関数のカリー化形式は、最初の引数をパラメータとして扱い、関数群を作成します。家族は各オブジェクトに対して次のように配置されますで関数は1つだけあります任意ので、。
この例では、それ自体が関数となり、引数として渡され、各要素をマッピングする関数を返します。にこれを表現する適切な表記法は冗長です。関数の集合に属する その間、関数の集合に属するつまり、地図に次のようなものになりますこの表記法では、これは、最初のセットからオブジェクトを受け取り、2番目のセットのオブジェクトを返す関数なので、次のように書きます。これはやや非公式な例です。「対象」と「機能」の意味に関するより正確な定義は後述します。これらの定義は文脈によって異なり、扱う理論によっても形が変わります。
カリー化は部分適用と関連していますが、同じではありません。[ 1 ] [ 2 ]上記の例は部分適用を説明するために使用できます。非常によく似ています。部分適用は関数です。ペアを取るそして引数としてまとめて返され、上記と同じ表記法を用いると、部分適用は次の式で表される。このように記述すると、適用はカリー化に付随するものと見なすことができる。
2つ以上の引数を持つ関数のカリー化は、帰納法によって定義できる。
カリー化は、実用的および理論的な両方の場面で役立ちます。関数型プログラミング言語やその他多くの言語では、関数や例外に引数を渡す方法を自動的に管理する方法を提供します。理論計算機科学では、引数が1つしかないより単純な理論モデルで、複数の引数を持つ関数を研究する方法を提供します。カリー化と非カリー化の厳密な概念の最も一般的な設定は、閉じたモノイド圏にあり、これは、証明とプログラムのカリー・ハワード対応を量子力学、コボルディズム、弦理論など、他の多くの構造との対応に大きく一般化することの基礎となっています。[ 3 ]
カレー風味という概念はゴットロープ・フレーゲによって導入され、[ 4 ] [ 5 ]モーゼス・シェーンフィンケルによって発展させられ、[ 6 ] [ 5 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ 11 ]ハスケル・カリー によってさらに発展させられた。[ 8 ] [ 10 ] [ 12 ] [ 13 ]
アンカリー化はカリー化への双対変換であり、脱機能化の一形態と見なすことができる。関数を受け取る。戻り値が別の関数である、新しい関数を生成する両方の引数をパラメータとして受け取るそして結果として、適用が返される。そしてその後、これらの議論に対して。このプロセスは反復可能である。
カリー化は、複数の引数を取る関数を扱い、関数が1つの引数しか取らないフレームワークでそれらを使用する方法を提供します。たとえば、一部の解析的手法は、単一の引数を持つ関数にのみ適用できます。実用的な関数は、これよりも多くの引数を取ることがよくあります。フレーゲは、複数の引数を持つ関数を代わりに単一の引数を持つ関数の連鎖に変換できるため、単一の引数の場合の解決策を提供すれば十分であることを示しました。この変換は、現在カリー化として知られているプロセスです。[ 14 ]数学的解析やコンピュータ プログラミングで通常遭遇する可能性のあるすべての「通常の」関数はカリー化できます。ただし、カリー化が不可能なカテゴリがあります。カリー化が可能な最も一般的なカテゴリは、閉じたモノイド カテゴリです。
プログラミング言語の中には、複数の引数を扱う際にほぼ必ずカリー化された関数を用いるものがあります。代表的な例としては、MLやHaskellが挙げられます。これらの言語では、すべての関数が引数を1つだけ持ちます。この特性はラムダ計算から受け継がれたもので、ラムダ計算では複数の引数を持つ関数は通常カリー化された形式で表現されます。
カリー化は部分適用と関連していますが、同じではありません。[ 1 ] [ 2 ]実際には、クロージャのプログラミング技術を使用して、カリー化された関数とともに移動する環境に引数を隠すことで、部分適用と一種のカリー化を実行できます。
「Currying」の「Curry」は、この概念を広く用いた論理学者ハスケル・カリーに由来するが、モーゼス・シェーンフィンケルはカリーより6年前にこの考えを持っていた。[ 10 ]別名「シェーンフィンケル化」も提案されている。[ 15 ]数学の文脈では、この原理は1893年のフレーゲの研究に遡ることができる。[ 4 ] [ 5 ]
「currying」という言葉の考案者は明確ではありません。David Turner は、この言葉はChristopher Stracheyが1967 年の講義ノート「 Fundamental Concepts in Programming Languages 」で造語したと述べていますが[ 16 ]、その資料では概念を「Schönfinkel が考案した装置」として紹介しており、「currying」という用語は使用されていません。一方、Curry は後に高階関数の文脈で言及されています。[ 7 ] John C. Reynolds は1972 年の論文で「currying」を定義しましたが、この用語を造語したとは主張していません。[ 8 ]
カリー化は、まず非公式な定義から始めると最も理解しやすく、その後、さまざまな領域に合わせて形を変えることができます。まず、いくつかの表記法を確立する必要があります。表記法は、すべての関数を表します。に。 もしこのような関数では、次のように書きます。。 させての要素の順序対を表すそしてそれぞれ、すなわち、デカルト積そして。 ここ、そしてこれらは集合である場合もあれば、型である場合もあり、あるいは以下で説明するように他の種類のオブジェクトである場合もある。
関数が与えられた場合
カリー化によって新しい関数が構築される
つまり、型の引数を取るそして、型の関数を返します。定義は
のためにタイプのそしてタイプの我々はまたこう書く
アンカリングは逆変換であり、その右随伴関数である関数の観点から最も簡単に理解できます。
集合論では、表記法は、集合からの関数の集合を表すために使用されます。セットへカリー化は、集合間の自然な全単射である。関数からに、そしてセット関数から関数セットへに記号で表すと:
実際、この自然な全単射こそが、関数の集合に対する指数表記を正当化する根拠となる。カリー化のすべての場合と同様に、上記の式は随伴関数のペアを表している。すなわち、任意の固定集合に対して、ファンクターファンクターの左随伴である。
集合のカテゴリーでは、オブジェクトこれは指数オブジェクトと呼ばれます。
関数空間の理論、例えば関数解析やホモトピー理論では、位相空間間の連続関数に関心を持つのが一般的である。(Homファンクター)は、すべての関数の集合に対してに、そして表記法を使用する連続関数のサブセットを表す。ここで、全単射
一方、アンカリー化は逆マップです。連続関数からにコンパクト開位相が与えられ、空間がは局所的にコンパクトなハウスドルフである。
は同相写像です。これは、の場合にも当てはまります。、そしてコンパクトに生成される、[ 17 ] :第5章[ 18 ]、ただし、より多くのケースがある。[ 19 ] [ 20 ]
有用な帰結の一つは、関数が連続であるのは、そのカリー化された形式が連続である場合に限るということです。もう一つの重要な結果は、この文脈では通常「評価」と呼ばれる適用マップが連続であるということです( evalはコンピュータサイエンスでは厳密に異なる概念であることに注意してください)。つまり、
連続であるときコンパクトオープンで局所コンパクトハウスドルフ。[ 21 ]これらの2つの結果は、ホモトピーの連続性を確立する上で中心となる。つまり、単位間隔、 となることによっては、2 つの関数のホモトピーとして考えることができる。にまたは同等に、単一の(連続した)パス。
代数トポロジーにおいて、カリー化はエックマン・ヒルトン双対性の例として用いられ、様々な場面で重要な役割を果たします。例えば、ループ空間は縮約サスペンションに随伴します。これは一般的に次のように表記されます。
どこは写像のホモトピー類の集合である。、 そしてAの懸垂であり、はAのループ空間です。本質的に、サスペンションは、の直積として見ることができる。単位区間と、等価関係を法として、区間をループに変換する。カリー化された形式は、空間をマッピングする。ループから関数空間へつまり、の中へ[ 21 ]それからは、サスペンションをループ空間に写像する随伴関手であり、アンカリー化はその双対である。[ 21 ]
マッピングコーンとマッピングファイバー(共ファイブレーションとファイブレーション)[ 17 ]の双対性:第6章、第7章は、カリー化の一形態として理解することができ、それが長完全および共完全プッペシーケンスの双対性につながります。
ホモロジー代数では、カリー化とアンカリー化の関係はテンソルホム随伴として知られています。ここで興味深い展開が生じます。Homファンクターとテンソル積ファンクターは、正確なシーケンスに持ち上げられない可能性があります。これがExt ファンクターとTor ファンクターの定義につながります。
順序理論、部分的に順序付けられた集合の束の理論では、は、格子にスコット位相が与えられたときに連続関数になります。[ 22 ]スコット連続関数は、ラムダ計算のセマンティクスを提供する試みの中で最初に研究されました(通常の集合論では不十分であるため)。より一般的には、スコット連続関数は現在、コンピュータアルゴリズムの表示的セマンティクスの研究を含む領域理論で研究されています。スコット位相は、位相空間のカテゴリで遭遇する可能性のある多くの一般的な位相とはかなり異なることに注意してください。スコット位相は通常より細かく、厳密ではありません。
連続性の概念はホモトピー型理論に登場し、大まかに言えば、2つのコンピュータプログラムがホモトピックである、つまり同じ結果を計算するとは、一方のプログラムから他方のプログラムへ「連続的に」リファクタリングできる場合を指す。
理論計算機科学において、カリー化は、関数が単一の引数しか取らないラムダ計算のような非常に単純な理論モデルにおいて、複数の引数を持つ関数を研究する方法を提供する。関数を考えてみよう。2 つの引数を取り、型がこれは、 x が次の型でなければならないことを意味すると理解されるべきである。yは型である必要があります、そして関数自体は型を返しますfのカリー化形式は次のように定義されます。
どこはラムダ計算の抽象化器です。curry は入力として、型の関数を受け取ります。カレーの種類自体が
→演算子は右結合であると考えられることが多いので、カリー化された関数型はしばしば次のように書かれる逆に、関数適用は左結合であると考えられているため、と同等
つまり、括弧は適用順序を明確にするために必ずしも必要ではない。
カリー化された関数は、クロージャをサポートするあらゆるプログラミング言語で使用できます。ただし、効率上の理由から、一般的にはカリー化されていない関数が好まれます。なぜなら、ほとんどの関数呼び出しにおいて、部分適用やクロージャ作成のオーバーヘッドを回避できるからです。
型理論では、コンピュータサイエンスにおける型システムの一般的な概念が、特定の型の代数として形式化されます。たとえば、意図はそしてはタイプであり、矢印はは型コンストラクタであり、具体的には関数型または矢印型です。同様に、デカルト積型の は、積型コンストラクタによって構築されます。。
型理論的なアプローチは、MLや、そこから派生し影響を受けたCaml、Haskell、F#などのプログラミング言語で表現されています。
型理論に基づくアプローチは、後述するように、圏論の言語を自然に補完するものです。これは、圏、特にモノイド圏には内部言語があり、単純型付きラムダ計算がそのような言語の最も顕著な例であるためです。この文脈において重要なのは、ラムダ計算が単一の型コンストラクタである矢印型から構築できる点です。カリー化によって、この言語には自然積型が付与されます。圏内のオブジェクトと型との対応関係により、プログラミング言語を(カリー・ハワード対応を介して)論理体系として、また後述するように他の種類の数学体系として再解釈することが可能になります。
カリー・ハワード対応の下では、カリー化と非カリー化の存在は、論理定理と同等である。(エクスポートとも呼ばれる)タプル(積型)は論理における論理積に対応し、関数型は含意に対応する。
指数オブジェクトハイティング代数のカテゴリーでは、通常、実質含意として記述される。分配的ハイティング代数はブール代数であり、指数オブジェクトは明示的な形式を持つ。それによって、指数オブジェクトが実際には物質的含意であることが明らかになる。[ 23 ]
上記のカリー化と非カリー化の概念は、圏論において最も一般的で抽象的な形で表現される。カリー化は指数的対象の普遍的な性質であり、デカルト閉圏における随伴を生み出す。すなわち、二項積からの射の間には自然な同型が存在する。そして指数オブジェクトへの射。
これは、閉じたモノイド圏におけるより広い結果に一般化されます。カリー化とは、テンソル積と内部 Homが随伴関手であるという記述です。つまり、すべての対象に対して自然な同型性が存在する:
ここで、Hom は、圏内のすべての射の (外部) Hom 関数を表し、は、閉じたモノイド圏における内部ホム関手を表します。集合の圏では、この2つは同じです。積がデカルト積の場合、内部ホムは指数オブジェクトになる。
カリー化は、2つの方法で破綻する可能性があります。1つは、圏が閉じていないため、内部ホム関手がない場合です(おそらく、そのような関手には複数の選択肢があるため)。もう1つは、圏がモノイド圏ではないため、積がない場合です(つまり、対象のペアを記述する方法がない場合)。積と内部ホムの両方を持つ圏は、まさに閉じたモノイド圏です。
デカルト閉圏の設定は古典論理の議論には十分であるが、より一般的なモノイド閉圏の設定は量子計算に適している。[ 24 ]
これら2つの違いは、デカルト圏(集合の圏、完全半順序、ハイティング代数など)の積は単にデカルト積であり、項目の順序対(またはリスト)として解釈される点です。単純型付きラムダ計算はデカルト閉圏の内部言語であり、そのため、LISP、Scheme、および多くの関数型プログラミング言語の型理論では、ペアとリストが主要な型となっています。
対照的に、モノイド圏(ヒルベルト空間や関数解析のベクトル空間など)の積はテンソル積です。このような圏の内部言語は線形論理であり、量子論理の一形態です。対応する型システムは線形型システムです。このような圏は量子もつれ状態を記述するのに適しており、より一般的には、カリー・ハワード対応を量子力学、代数トポロジーのコボルディズム、弦理論に大きく一般化することができます。[ 3 ]線形型システムと線形論理は、相互排他ロックや自動販売機の動作などの同期プリミティブを記述するのに役立ちます。
カリー化と部分関数適用はしばしば混同される。[ 1 ] [ 2 ]両者の重要な違いの1つは、部分適用された関数の呼び出しは、カリー化チェーンの下流にある別の関数ではなく、結果をすぐに返すことである。この違いは、引数の数が2より大きい関数で明確に説明できる。[ 25 ]
型の関数が与えられた場合カレーを作るとつまり、最初の関数の評価は次のように表されるかもしれない。カリー化された関数の評価は次のように表されます。各引数を、前の呼び出しで返された単一引数関数に順番に適用します。呼び出し後に注意すると、引数を 1 つだけ取り、別の関数を返す関数が得られ、引数を 2 つ取る関数は得られません。
対照的に、部分関数適用とは、関数の引数の数を固定して、引数の数が少ない別の関数を生成するプロセスを指します。上記のように、最初の引数を固定(または「バインド」)して、次の型の関数を生成することができます。この関数の評価は次のように表すことができます。なお、この場合の部分関数適用の結果は、2つの引数を取る関数になります。
直感的に言えば、部分関数適用とは「関数の最初の引数を固定すると、残りの引数の関数が得られる」ということです。例えば、関数div が除算演算x / yを表す場合、パラメータxを 1 に固定したdiv (つまりdiv 1) は別の関数です。これは、引数の乗法逆数を返す関数inv ( y ) = 1/ yと同じです。
部分適用の実際的な動機は、関数に引数の一部のみを与えることで得られる関数が非常に有用であることが多いという点にあります。例えば、多くのプログラミング言語には、 に似た関数や演算子がありますplus_one。部分適用を用いることで、これらの関数を簡単に定義できます。例えば、最初の引数として 1 を境界値とする加算演算子を表す関数を作成するなどです。
部分適用は、例えば、固定点でカリー化された関数を評価することと見なすことができる。そしてそれからまたは単にどこカリーのfの最初のパラメータ。
したがって、部分適用は固定点におけるカリー化関数に還元される。さらに、固定点におけるカリー化関数は(自明に)部分適用である。さらなる証拠として、任意の関数が与えられた場合、関数は次のように定義される可能性がある。したがって、部分適用は単一のカレー操作に還元できる。そのため、カレーは、多くの理論的なケースでは再帰的に適用されることが多いが、理論的には(操作として考えると)部分適用と区別できない操作として定義するのがより適切である。
したがって、部分適用とは、ある関数の入力の順序付けに対してカリー演算子を一度適用した結果として得られる客観的な結果と定義できる。
の連続適用に還元する装置が Schönfinkel によって考案されました。
すべての関数が単一の引数を受け取る言語に二項演算を導入するという問題を解決するために、カリー化(論理学者H.カリーにちなんで名付けられた)と呼ばれる手法を用いました。(査読者は、「カリー化」の方が味は良いが、「美的感覚」の方がより正確かもしれないとコメントしています。)ジョン・C・レイノルズ(1998)著「高階プログラミング言語のための定義的インタプリタ」として再出版。高階および記号 計算。11 ( 4 )。ボストン:クルーワー・アカデミック・パブリッシャーズ:363–397。doi:10.1023 /A:1010027404223。13 –シラキュース大学:工学部およびコンピュータサイエンス学部 - 旧学科、センター、研究所およびプロジェクト経由。
私がこの関数の見方を多用したため、「カリー化」と呼ぶ人もいますが、シェーンフィンケルはこのアイデアを私より約6年前に持っていました。