関数のカリー化
複数の引数を取る関数を関数チェーンに変換します。
「関数のカリー化」はCoddyKit上の無料JavaScript Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJavaScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 JavaScript Academyコースには全4レッスンが含まれています。
カリー化とは
カリー化とは、多数の引数を受け取る関数を、それぞれが1つの引数を受け取る関数の連続に変換することです。
add(1, 2, 3)の代わりにadd(1)(2)(3)と呼び出します。すべての引数が集まるまで、呼び出すたびに次の関数が返されます。
手作業でカリー化する
カリー化を理解する最も分かりやすい方法は、ネストした関数を記述することです。それぞれの関数が次の関数を返し、前の引数をクロージャとして取り込みます。
function add(a) {
return function (b) {
return function (c) {
return a + b + c;
};
};
}
console.log(add(1)(2)(3));ネストしたアロー関数の戻り値
アロー関数を使うと、カリー化した定義を短く書けます。各=>が次のアロー関数を返し、最後の関数が処理を実行します。
const add = a => b => c => a + b + c;
console.log(add(1)(2)(3));
console.log(add(10)(20)(30));クロージャが引数を記憶する
カリー化はクロージャに依存しています。返された各関数は、外側のスコープにある変数への参照を保持するため、最後の呼び出しが実行されるまで前の引数を利用できます。
const greet = greeting => name => greeting + ', ' + name + '!';
const sayHi = greet('Hi');
console.log(sayHi('Ada'));
console.log(sayHi('Grace'));段階的に呼び出す
すべての引数を一度に適用する必要はありません。途中で止め、部分的に適用した結果を変数に保存して再利用できます。
const add = a => b => c => a + b + c;
const addOne = add(1);
const addOneAndTwo = addOne(2);
console.log(addOneAndTwo(3));
console.log(addOneAndTwo(100));汎用的なcurryヘルパー
ネストした関数を手作業で書くのは面倒です。汎用的なcurryヘルパーは、必要な数の引数が集まるまで引数を収集し、その後で元の関数を呼び出します。
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn(...args);
}
return (...more) => curried(...args, ...more);
};
}
const add = curry((a, b, c) => a + b + c);
console.log(add(1)(2)(3));curryによる柔軟な呼び出し
優れたcurryヘルパーは、引数をどのようにグループ化して渡しても受け付けます。fn.lengthによって、元の関数が宣言したパラメーター数がわかります。
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn(...args);
}
return (...more) => curried(...args, ...more);
};
}
const add = curry((a, b, c) => a + b + c);
console.log(add(1, 2, 3));
console.log(add(1, 2)(3));
console.log(add(1)(2, 3));特化のためのカリー化
カリー化を使うと、特化が自然に行えます。最初の引数を適用し、返された関数を複数の呼び出しで再利用します。
const multiply = a => b => a * b;
const double = multiply(2);
const triple = multiply(3);
console.log(double(5));
console.log(triple(5));配列メソッドでのカリー化
カリー化された関数は、mapやfilterにそのまま組み込めます。どちらも、各要素を受け取る準備ができた1引数関数を生成するためです。
const greaterThan = min => value => value > min;
const over10 = greaterThan(10);
console.log([5, 12, 8, 20].filter(over10));カリー化と部分適用の違い
部分適用では一部の引数を固定し、残りを後で1回の呼び出しで渡します。カリー化では、関数を常に1引数の呼び出しの連鎖に分解します。
カリー化は、部分適用を完全に分解した、特定の形式の1つです。
const partial = (a, b) => c => a + b + c;
const curried = a => b => c => a + b + c;
console.log(partial(1, 2)(3));
console.log(curried(1)(2)(3));なぜカリー化するのか
カリー化を使うと、小さく、組み合わせやすく、再利用可能な関数を作りやすくなります。次に学ぶ関数合成とも自然に組み合わせられます。重要な点は、カリー化された関数が「未完成」になることはないということです。必要な引数がそろうまで、単に別の関数を返し続けます。
const tag = name => content => '<' + name + '>' + content + '</' + name + '>';
const bold = tag('b');
console.log(bold('important'));
console.log(tag('i')('slanted'));理解度チェック
const add = a => b => c => a + b + c;が与えられたとき、add(1)(2)は何に評価されますか。
まとめ:カリー化
関数を1引数の連鎖に分解する方法を学びました。
- カリー化された関数は、クロージャを通じて引数ごとに新しい関数を返します。
- ネストしたアロー関数を使うと、簡潔にカリー化された定義を書けます。
- 汎用的な
curryヘルパーは、fn.lengthを使って引数が十分に渡されたかを判断します。 - カリー化によって、きれいな特化と合成が可能になります。
よくある質問
「関数のカリー化」レッスンは無料ですか?
はい。「関数のカリー化」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、JavaScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 JavaScript Academyコースには全4レッスンが含まれています。
「関数のカリー化」で何を学びますか?
複数の引数を取る関数を関数チェーンに変換します。 ブラウザで直接実行するハンズオンコードでJavaScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
JavaScript Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのJavaScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「関数のカリー化」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このJavaScript Academyレッスンでコードを書いて実行できますか?
はい。すべてのJavaScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 部分適用
- 関数のカリー化
- 関数合成
- pipe と compose を作成する