カーリー化(Currying)とは何か

複数の引数をとる関数を「引数1つずつ受け取る関数の連続」に変形すること を指すようです。

文系出身にとって、『は?』ってなります。。

ちなみに今まで私は通2引数関数は次のように書いてきました。

function add(a: number, b: number): number {
  return a + b;
}

これをカーリー化すると、以下のようになるかと思います。

const add =
  (a: number) =>
  (b: number): number =>
    a + b;

このように a を受け取る関数 → b を受け取る関数 という階段構造になります。

カーリー化のメリット

カーリー化は「数学のテクニック」に見えますが、 実際には 実用的な利点 がいくつもある気がします。文系目線です。

1. 一部の値だけ先に“設定”できる(部分的に固定する)

カーリー化されている関数は、一部の引数だけ先に決めた状態を作れます。

const withTax =
  (rate: number) =>
  (price: number): number =>
    price * rate;

const tax10 = withTax(0.1);
const tax8 = withTax(0.08);

console.log(tax10(1000)); // 100
console.log(tax8(1000));  // 80

2. 各ステップにログを仕込める

カーリー化の隠れた強みがこれです。 ステップが分かれている分、ログをピンポイントで入れられる ようになります。

const calc =
  (a: number) => {
    console.log('a を受け取った:', a);
    return (b: number): number => {
      console.log('b を受け取った:', b);
      const result = a + b;
      console.log('結果:', result);
      return result;
    };
  };

calc(2)(3);
// a を受け取った: 2
// b を受け取った: 3
// 結果: 5

個人的にコレが凄く良い気がします。デバックはブレイクポイントを置かないでログを出して解析するタイプなのでこの方法はすぐに実践に投入しました。

3. 小さく分解されるのでテストしやすい

カーリー化により、 • a を受け取る処理 • b を受け取る処理 • 計算処理

が自然と分離されるため、 単体テストの書きやすさが大きく向上します。

「a がセットされた状態だけテストする」などの細かい検証も可能です。

4. 専用の関数を簡単に作れる(再利用しやすい)

汎用的な関数をベースに “固定値をセットした専用関数” を作ることができます。

const multiply =
  (a: number) =>
  (b: number): number =>
    a * b;

const double = multiply(2);
const triple = multiply(3);

console.log(double(10)); // 20
console.log(triple(10)); // 30

5. 関数型プログラミングの基礎になる

React、Redux、Ramda、Next.js など、 最近の JavaScript / TypeScript では「関数を渡す・組み合わせる」文化が強く、 カーリー化を理解しているとコードリーディングが非常に楽になる気がします!

TypeScriptの場合、型が「今何が固定されて、次に何が必要か」を表現してくれるため、 エディタ補完の体験も向上するので書く方も楽になるかと。。

まとめ

  • カーリー化とは 複数引数の関数を、引数1つずつ受け取る関数へ変形する技法。
  • メリット • 一部の値だけ先に“設定”できる • ステップごとにログを仕込める • テストがしやすい • 専用関数が作りやすく再利用性が高い • React など現代JS/TSとの相性が良い

数学的に見えるかもしれませんが、 実際には デバッグ性・保守性・再利用性を上げるための便利な道具 ?になるのかな。

(本記事には広告が含まれています)