カリー化
複数の引数を取る関数を、1 つの引数を取る関数の連鎖に変換する手法
関数型プログラミングJavaScript
カリー化とは
カリー化 (Currying) は、複数の引数を取る関数 f(a, b, c) を、1 つの引数を取る関数の連鎖 f(a)(b)(c) に変換する手法である。Haskell Curry にちなんで名付けられた。部分適用と組み合わせて、関数の再利用性を高める。
基本
// 通常の関数
function add(a: number, b: number): number {
return a + b;
}
add(1, 2); // 3
// カリー化
function curriedAdd(a: number) {
return (b: number) => a + b;
}
curriedAdd(1)(2); // 3
// 部分適用: 引数を固定した新しい関数を作る
const add10 = curriedAdd(10);
add10(5); // 15
add10(20); // 30
実用的な例
// ログレベルを固定したロガー
const createLogger = (level: string) => (message: string) =>
console.log(`[${level}] ${message}`);
const info = createLogger('INFO');
const error = createLogger('ERROR');
info('Server started'); // [INFO] Server started
error('DB connection failed'); // [ERROR] DB connection failed
// API エンドポイントを固定した fetch
const createFetcher = (baseUrl: string) => (path: string) =>
fetch(`${baseUrl}${path}`).then(r => r.json());
const api = createFetcher('https://api.example.com');
const users = await api('/users');
const orders = await api('/orders');
汎用的なカリー化関数
function curry<A, B, C>(fn: (a: A, b: B) => C): (a: A) => (b: B) => C {
return (a: A) => (b: B) => fn(a, b);
}
const multiply = curry((a: number, b: number) => a * b);
const double = multiply(2);
double(5); // 10
カリー化 vs 部分適用
| 概念 | 説明 |
|---|---|
| カリー化 | f(a, b) → f(a)(b) (全引数を 1 つずつ) |
| 部分適用 | f(a, b) → g(b) (一部の引数を固定) |
カリー化は部分適用を可能にする手法。
React での活用
// イベントハンドラの部分適用
function TodoList({ items, onDelete }: Props) {
return (
<ul>
{items.map(item => (
<li key={item.id}>
{item.text}
<button onClick={() => onDelete(item.id)}>Delete</button>
</li>
))}
</ul>
);
}
使いすぎに注意
カリー化を多用するとコードが読みにくくなる。明確なメリット (部分適用による再利用) がある場合にのみ使う。
カリー化の背景や設計思想は関連書籍に詳しい。