実際のカレーと部分関数の適用の違いは何ですか


8

部分的な関数の適用とカリー化された関数(f(X x Y x Z) -> Nvs f(X -> (Y -> (Z -> N))))の違いを理解していますが、ソフトウェアの開発時にこの違いの結果がどうなるかわかりません。

回答:


5

元々、カリー化は実際的なプログラミング手法ではなく、分析を単純化することでした。ラムダ計算では、すべての関数は単項です。カレーは、同様の理由で言語レベルでよく使用されます:計算モデルの単純化。

名前付きの便利な関数を、引数を修正するだけで、より一般的な別の関数として実装できる場合に、部分的なアプリケーションが使用されます。

それらは、計算のさまざまな部分を含む別個の形式のままです。考慮してください:

x=>y=>z=>f(x,y)
(y,z)=>f(0,y,z)

カリー化された関数は引数にバインドされた値を持たず、特定の順序で引数を取ります。関数をカレー化すると、結果をカレー化したり、関数が引数をとる順序を変更したりすることはありません(ただし、そうするためにアンカレーやカレー化は可能です)。対照的に、部分関数は引数にバインドされた値を持ち、残りの引数に沿ってさらに部分的に適用できます。

カリー化された関数の適用は、部分的な適用に近い(結局のところ、関数をカリー化せずにそのままにしておきます。ある時点で、適用することになります)。これは、用途が交差し始める場所です。これを行う場合、カレーは、部分的な適用に向けた2つのステップのうちの最初のステップにすぎません。


2

あなたの質問は次のように言い換えることができると思います:なぜ言語はカレーを持っているのですか?

それは主に利便性の問題です:

Ocamlでは、

 let sum3 x y z = x + y + z;;
 let foo xx yy ll = List.map (sum3 xx yy) ll;;

Schemeでは、無名関数を明示的に作成する必要があります

 (define (sum3 x y z) (+ x y z))
 (define (foo xx yy ll) (map (lambda (zz) (sum3 xx yy zz)) ll))  

部分的なアプリケーションとカリー化を伴う言語では、あらゆる場所で部分的なクロージャーを作成しないように、最適化を行う必要があります。実装が常にsum3次のように定義されているかのように適用したくない場合

 let sum3 x = 
    fun y -> 
      (fun z -> x + y + z)

つまり、計算時に2つの中間クロージャーを割り当てますsum3 1 2 3(理解され、((sum3 1) 2) 3... として解析されます)。合計をすぐに計算する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.