web-dev-qa-db-ja.com

カレー機能の実際の使用例は?

カレー機能の実際の使用例を見つけ、カレーを使用するメリットを得るのに苦労しました。

カレー機能をググると、次のような例がよく見られます

let add = x => y => x + y;
let add10 = add(10);
console.log(add10(20));

この例では、カレーを使用することの価値は本当にないと思います。

これの答えを読んだ後SO https://stackoverflow.com/questions/113780/javascript-curry-what-are-the-practical-applications Iそれを使用する利点はまだわかりません。

たとえば、最高得点の回答はコンバーターの例ですが、別の回答が示すように、その例はカレーなしで書き直すことができます。

私も答えを読みます カレーの利点は何ですか? (ディスカッションはjavascriptに限定されていませんが)カリーなしでカリーバージョンを書き直すことができる(jsで)とまだ感じています。

それで、誰かが私にJavaScriptでカレーを使用することの「本当の」利点/利点を示すことができますか?

----更新----

私が得た答えを除いて、私も見つけます ログの例 ここにそれを使用する利点を示します。

8
Qiulang

私は自分でカリー化を使用したことはほとんどありませんが、これが有用であることが判明した最近の例です。私はゲームのコーディングをしていました Battlesnake が、これは多くのゲームに当てはまります。彼らはあなたにあなたのヘビ、敵のヘビ、そして食べ物の場所を与える様々な配列を提供します。特定の{x、y}ポイントへの移動を検討していて、別のヘビ、食べ物、または自分自身が含まれているかどうかを確認するとします。最初のパスは、このようなコードを書くことです(私はfunctionと新しい矢印の組み合わせを使用します)

_// utility function
function samePoint(p1, p2) {
  return (p1.x === p2.x) && (p1.y === p2.y);
}
_

コードのどこかに行く

_let possibleMove = {x,y}; // where you are thinking of moving
...
if (foodArray.some((p) => samePoint(p, possibleMove )) {
  // this move looks tasty, give it a bonus value...
}
_

悪くはありませんが、コードの多くの場所でこれを行うので、少々面倒で不格好です。そして、私の経験から、2つの議論は簡単に混乱します。 :-(根本的な問題はsome()(またはfind())がsingle引数のみを取る関数を受け入れ、そして本当に2つ必要なことです。引数、2つのポイントです。カレーについて考えてみてください!ここでは多くの場合矢印を使用しますが、ネストされた関数の方がわかりやすいでしょう:

_function samePointAs(p1) {
  return function(p2) {
    return samePoint(p1, p2);
  }
}
_

次に、あなたの「その食べ物ですか」テストは

_let possibleMove = {x,y}; // where you are thinking of moving
...
if (foodArray.some(samePointAs(possibleMove )) {
  // this move looks tasty, give it a bonus value...
}
_

これはあなたをインターネットの億万長者にするでしょうか?おそらく違います。しかし、それは単純化し、この場合、コードを明確にします。

8
user949300

あなたの例でカレーすることは実際には意味がありません、私は同意します。カレーの機能を確認するには、それをより高次の関数、つまり別の関数をパラメーターとして取る関数と組み合わせる必要があります。

この最も一般的な例は、マップ、フィルター、および縮小ですが、別の一般的な状況はコールバックです。関数を部分的に適用する場合、部分的に適用された関数をこれらの高次関数に渡すことができます。関数を使用したい場合のほとんどが部分的なアプリケーション用であり、別の高次関数に渡すことができる場合、カリー化は理にかなっています。

より具体的な例は次のようになります。

let array1 = [1, 4, 9, 16];
let add = x => y => x + y;
array2 = array1.map(foo ? add(10) : add(20));

必要なときに通常の関数から無名/矢印関数をいつでも作成できるため、カリー化は必要ありませんが、場合によっては、通常の関数と比較してカリー関数を使用すると非常に便利です(他の状況では、物事を煩わしく遅くする)。

14
Lie Ryan