今回は部分適用について学びましょう。まず関数の概要を見てみましょう:
数学では、関数は各入力値と一意の出力値の間の対応関係を記述します。記号は f(x) です。たとえば、式 f(x)=x2 は、各入力値 x が固有の出力値 x2 に関連付けられている関数 f を表します。
つまり、入力値が 3 の場合、対応する出力値は 9 になります。また、 g(x,y) = xy には 2 つのパラメータ x と y があり、その積 xy が値になります。関数は上記で説明されています (便宜上、x と y が両方とも int であると仮定します)。f(x) を別の方法で表現できる例を 2 つ示します。 x2) 、つまり、 f を x2 にマッピングした後、 int -> int; と記述されます。
int を受け入れ、int を返します。 g(x,y) をもう一度見ると、 x -> y -> z(xy) と表すことができます。つまり、x、y は、int -> int -> int として記述され、z から g にマッピングされます。 g(x,y) 関数を見て、JavaScript を使用してそれを実装してみましょう:
function g(x,y){
return x*y;
}
これは完璧で、数学的定義に非常に近いです。 2 つのパラメータ x と y を順番に受け入れます。そして両者の積を返します。ただし、x=n (n は自然数) など、x が定数の場合。したがって、g(n,y)=ny となります。これは定数と変数の積となり、パラメーター y を受け取り ny を返します。つまり、int -> int と書かれた y -> z(ny) のマッピングになります。したがって、上記の作業は次のように理解できます。 g(x,y) はパラメータ int を受け入れ、関数 int ->int を返します。この返される関数は int のみを受け入れ、int を返します。これを JavaScript で表現してみましょう:
var h = g(2 );
h ここで、関数 h(y)=2y を表します。このようにして、h(5)=10、h(13)=26 などとなります。
h(5); (13) ;
この手法は、複数のパラメーターを必要とする関数形式を、単一のパラメーターを受け入れる関数チェーンに変換するもので、通常、これは Haskell に敬意を表して付けられた名前です。カリーだが、彼は最初にプロポーズされたわけではない。しかし、残念ながら、JavaScript はそのような機能をサポートしていません。したがって、このような機能を実装するには、複雑ではないいくつかの作業が必要になります。主な目的はパラメータを保存し、関数チェーン内の次の関数の呼び出しを待機しているときに前のパラメータを取り出し、最終的に戻り値が取得されるまでチェーン内の次の関数に渡し続けることです。まず次のコードを見てください:
function atarr(a,index){
varindex=index||0,args = new Array(a.length -index)
for(var i in a){
if(i> =index) args[i -index]=a[i];
}
return args;
function m(scope,fn){
if(arguments.lengthvar p = atarr(arguments,2);
var args = atarr(arguments);
return fn.apply(scope) ,p.concat(args ));
}
}
テストコード:
return a b;
} var plus2 = m(null,plus) ,2);
console.log(plus2(10));
//結果
12
これが私たちの目標であり、実装されました。上記の atarr 関数は、arguments オブジェクト内の指定された位置から始まるパラメーターを取り出し、配列に保存します。 m 関数が主役で、以前に定義したタスクを完了し、関数チェーン上のパラメーターを保存し、残りのパラメーターを受け入れる関数を返します。テスト コードの plus 関数は、もともと 2 つのパラメーター a と b を受け入れ、a と b の合計を返しました。ただし、plus2 は 1 つのパラメーター b を受け入れ、それを 2 に加算します。 2 と b の合計は int -> int を返します。
上記の作業の一部を通じて、JavaScript で部分アプリケーションを実装し、hitch2 で Dojo フレームワークにドメイン バインディングと部分を実装しました。興味があれば、そのソース コードを読んでみてください。これも非常にシンプルで明確です。