関数型プログラミングの基本|JS/TSで学ぶ実践入門

プログラミング言語

関数型プログラミング(FP)は「副作用を抑え、関数を組み合わせる」プログラミングスタイルです。完全に関数型でなくとも、その考え方を取り入れるとコードがシンプルで読みやすくなります。本記事では、JavaScript/TypeScriptで学ぶ関数型の基本を解説します。

関数型の基本的な考え方

  • 純粋関数:同じ入力なら同じ出力、副作用なし
  • イミュータブル:値を変更せず新しい値を作る
  • 第一級関数:関数を引数・戻り値として扱う
  • 合成:小さな関数を組み合わせて大きな処理を作る

純粋関数とは

// 純粋
const add = (a, b) => a + b;

// 非純粋(副作用あり)
let counter = 0;
const inc = () => { counter++; return counter; };

イミュータブルなデータ操作

// NG:元の配列を変更
const arr = [1, 2, 3];
arr.push(4);

// OK:新しい配列を作る
const arr2 = [...arr, 4];

// オブジェクトも同じ
const user2 = { ...user, name: 'B' };

高階関数:map / filter / reduce

const nums = [1, 2, 3, 4, 5];

const doubled = nums.map(n => n * 2);
const evens = nums.filter(n => n % 2 === 0);
const sum = nums.reduce((a, b) => a + b, 0);

関数合成

const pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x);

const toUpper = s => s.toUpperCase();
const exclaim = s => s + '!';
const shout = pipe(toUpper, exclaim);

shout('hello'); // 'HELLO!'

カリー化(部分適用)

const add = (a) => (b) => a + b;
const add10 = add(10);
add10(5); // 15

Option / Resultパターン

例外ではなく「値で失敗を表す」。null/undefinedより明示的で安全です。

type Result<T, E> = { ok: true; value: T } | { ok: false; error: E };

function parseInt2(s: string): Result<number, string> {
  const n = Number(s);
  return Number.isFinite(n)
    ? { ok: true, value: n }
    : { ok: false, error: `invalid: ${s}` };
}

実務での活用

  • Reactのstate更新はイミュータブル前提(Immerも便利)
  • 配列処理はforよりmap/filter/reduce
  • 副作用(API呼び出し・DOM操作)は端に集める
  • テストは純粋関数中心に書くと楽

まとめ

関数型プログラミングは「全部関数型にする」ではなく、純粋関数・イミュータブル・高階関数といった発想を取り入れるだけで効果絶大です。日常のJS/TSコードに混ぜていけば、テストしやすく副作用に強いコードになっていきます。