0Pricing
JavaScript Academy · レッスン

関数のカリー化

複数の引数を取る関数を関数チェーンに変換します。

「関数のカリー化」は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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 部分適用
  2. 関数のカリー化
  3. 関数合成
  4. pipe と compose を作成する
← JavaScript Academyに戻る