Javascript関数コリック化(curry)

1818 ワード

関数コリック化curryingは、関数式プログラミングの非常に重要なシンボルです.その実装には、以下の条件を満たす必要があります.まず、関数はパラメータとして伝達されます.私たちはこの特性を頼りに多くの優雅でクールなコードを作成します.簡単な実現を見てみましょう.
一般的にaddSumの例を挙げますが、私も例外ではありません.
add = (num1)->
  return (num2)->
    return num1 + num2;
    
add3 = add(3);
add5 = add(5);

add3(5) #   8
add5(5) #   10
上記の例は実はすでにコリック化の実現に対して、とても良い理解があります.つまり「ステップ値」です.returnから出る匿名関数のために、最初のパラメータをクローズドによって保存します.だから私たちはaddによって定義された様々な新しい関数から来ることができる.
私たちはある関数をカリー化できるようにしますが、関数を作る時には、カリー化の特性がありますか?私達のadd関数を仮定して、初めは柯里化の特性を持たないで、私達はどのようにして柯里化することができますか?
add = (num1, num2)->
  return num1 + num2;

curry = (fn)->
  args = [].slice.call(arguments, 1);
  return ()->
    [].push.apply(args, arguments);
    return fn.apply(this, args);

add5 = curry(add, 5)
add5(3) #   8
原理は同じです.私たちはcurry関数を通じて、fnが必要とする初めてのパラメータを、匿名関数のために、クローズドによってargsの変数に保存させます.最後に2回目に必要なパラメータを組み合わせて、appyを使って一括でargsを導入し、操作を完了します.
上記のように、私達が見ているのは二歩に分けて値を求めることです.これは実は私達のより豊富な実際的な需要に合わないです.私たちはどうすれば関数のカリー化を私たちの必要なものに変えられますか?
まず私たちはルールを約束する必要があります.この規則はほとんどのGetter/Setter法と同じです.関数にパラメータがない場合は、Getterが実行されますが、パラメータがあれば、「Setter」が実行されます.(これもJavascriptが簡単な関数を再負荷する方法です.)
curry = (fn)->
  args = [];
  return ()->
    if arguments.length == 0
      return fn.apply(this, args);
    else
      [].push.apply(args, arguments);
      return arguments.callee;
      
addSum = ()->
  sum = 0;
  for num in arguments
    sum += num;
  return sum;

currySum = curry(addSum);

currySum(1, 2, 3);
currySum(1);
currySum(1);
currySum(1);
currySum(1);
currySum(); #    10
原理を実現するのも簡単です.クローズドすることで、毎回のパラメータをargs配列に保存しました.パラメータを参照せずにGetterを実行すると、直接にapply関数を通じて配列パラメータを導入します.導入したパラメータ配列をaddSum関数で処理すればいいです.
もっと多くのカーリー化の持ってくる妙味、あなたが実際に使う中で必要で、事細かに味わいます.この柔軟で確実な方法をマスターすれば、違った感じを与えることができると信じています.