1

次のような関数があります。

function curry(fn) {
    var args = [].slice.call(arguments, 1);
    return function() {
        return fn.call(this, args.concat([].slice.call(arguments)));
    };
}

私はいつも、それが関数がどのように見えるべきか、次のように機能するべきだと思っていました:

function add(a, b, c, d) {
   return a+b+c+d;
}


curry(add, 1, 2)(3, 4);

しかし、ウィキペディアの記事は次のように述べています

それぞれが単一の引数を持つ一連の関数として呼び出すことができます

したがって、カレーは次のようになります。

function curry(fn) {
    var args = [];
    return function curring() {
        args = args.concat([].slice.call(arguments));
        if (args.length >= fn.length) {
            return fn.apply(this, args);
        } else {
            return curring;
        }
    };
}

次のように使用できます。

function add(a, b, c, d) {
   return a+b+c+d;
}

curry(add)(1)(2)(3)(4);

私は正しいですか?

4

1 に答える 1

2

厳密に言えば、カリーcurry化は、多くの引数を持つ関数を、2 番目の関数のように、それぞれが 1 つの引数を持つ一連の関数に変換します。

  • それらすべてを (チェーンで) 呼び出すと、関数の完全な適用が得られ、元の関数と同じ結果が生成され
    curry(add)(1)(2)(3)(4)ます。add(1, 2, 3, 4)10

  • サブセットのみを呼び出すと、部分的に適用された関数が得られます。

    1. addOne = curry(add)(1);
    2. addOneAndTwo = addOne(2);
    3. addOneAndTwo(3)(4)戻り値10

Javascript では、カリー化は通常、最初の関数のように、部分適用の同義語として使用されますcurryプロトタイプのドキュメントの言い換え:

カレーは、引数を関数にカレー (バーンイン) し、新しい関数を返します。この関数は、call で呼び出されたときに、カレーされた引数 (新しいものと一緒に) を渡す元の関数を呼び出します。

詳細な説明については、カリー化と部分適用の違いを参照してください。

これは、 Evan BordenによるJavaScript での真のカレー関数の実用的な実装です。

いくつかの注意事項:

  • あなたの最初の機能でfn.callは、間違っています。を使用する必要がありますfn.apply。2 番目の引数として渡す配列は、引数のリストとして使用する必要がありcall、それを 1 つの引数としてのみ扱う必要があります。

  • curring2 番目の関数は、呼び出された各インスタンスが呼び出されたときに初期化されたキャプチャされたargs配列を変更するため、1 回だけ呼び出すことができるカリー化された関数を生成しますcurry

    例えば:

    1. addOne = curry(add)(1);に初期化されaddOneた独自の定義args[1]

    2. addOne(2)(3)(4)戻り10、変更argsする[1, 2, 3, 4]

    3. addOne(2)(3)(4)(2 回目) で失敗しaddOne(...) is not a function、呼び出し
      を試みるaddOne(2)add(1, 2, 3, 4, 2)

于 2013-08-25T21:34:38.300 に答える