📌

[関数型プログラミング]第一級関数と高階関数

2025/01/06に公開

第一級関数(First-Class Function)

1. 第一級関数とは?

プログラミングにおいて「第一級(First-Class)」とは、値を自由に扱える性質を指します。
JavaScriptの関数は「第一級オブジェクト」として扱えるため、以下のように値として利用できます:

  • 変数に関数を代入できる
  • 関数の引数として他の関数を渡すことができる
  • 関数の戻り値として別の関数を返すことができる

2. 第一級関数の例

  1. 変数に関数を代入できる
const sayHello = function() {
  console.log("Hello, World!");
};
sayHello(); // Hello, World!
  1. 関数の引数として他の関数を渡すことができる
function repeat(n, action) {
  for (let i = 0; i < n; i++) {
    action(i); // 渡された関数を実行
  }
}
repeat(3, console.log); // 0 1 2
  1. 関数の戻り値として別の関数を返すことができる
function createMultiplier(multiplier) {
  return function (value) {
    return value * multiplier;
  };
}
const double = createMultiplier(2); // 関数を返し、それを保存
console.log(double(5)); // 10

また、関数自体を別の変数に代入すると、任意のタイミングで評価して結果を生成できます。
以下の例では、double という変数に代入された関数はまだ実行されていません。
console.log(double(5)); のコードを通じて初めて実行されます。

3. 第一級関数の利点

組み合わせ: 小さな関数を組み合わせて複雑な動作を構築できます。
抽象化: 共通のパターンを関数にすることで再利用性を高められます。
配列データ処理の例

const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((num) => num * 2); // [2, 4, 6, 8, 10]
const filtered = numbers.filter((num) => num % 2 === 0); // [2, 4]

このコードでは、map と filter がそれぞれ関数を引数として受け取り処理を行っています。
これにより、コードの可読性と柔軟性が向上しています。

高階関数(Higher-Order Function)

高階関数とは、関数を値として扱う関数を指します。

大きく2つの種類に分けられます:

  • 関数を引数として受け取り実行する関数
  • 関数を生成して返す関数

1. 関数を引数として受け取り実行する関数

const apply1 = f => f(1);
const add2 = a => a + 2;
console.log(apply1(add2)); // 3

上記の apply1 関数は、関数を引数として受け取り、それを内部で実行しています。

const times = (f, n) => {
  let i = -1;
  while (++i < n) f(i);
};

times(console.log, 3); // 0 1 2

2. 関数を生成して返す関数(クロージャを生成する関数)

クロージャ(Closure) とは、返された関数が外部関数の変数にアクセスできる特性を指します。

const addMaker = a => b => a + b;

const add10 = addMaker(10);
console.log(add10(5)); // 15

まとめ

第一級関数は、関数を値のように扱える性質を持っています。この性質により、より柔軟で再利用可能なコードを記述できます。
高階関数は、関数を引数に取ったり、返り値として返すことで、動作を組み合わせたり、パターンを抽象化するのに役立ちます。

参考資料: JavaScript ES6+のための関数型プログラミングとJavaScript ES6+

Discussion