プログラミング基礎概念

高階関数 こうかいかんすう

関数型プログラミングコールバックラムダ式map/filter/reduceクロージャ第一級関数
高階関数について教えて

簡単に言うとこんな感じ!

関数を引数として受け取ったり、関数を返したりできる関数」のことだよ!料理レシピ(関数)を別のレシピに渡して「この手順でやって!」と指示するイメージ。コードを部品化して使い回しやすくする、現代プログラミングの重要テクニックなんだ!


高階関数とは

高階関数(Higher-Order Function)とは、「関数を引数として受け取る」または「関数を戻り値として返す」、あるいはその両方を行う関数のことです。これは関数型プログラミングの中核的な概念のひとつで、JavaScriptPythonScalaなど多くのモダンな言語で広くサポートされています。

高階関数が成り立つ前提として、第一級関数(First-Class Function)という性質が必要です。第一級関数とは、関数を数値や文字列と同じように「値」として扱える性質のこと。変数に代入したり、引数に渡したり、戻り値にしたりが自由にできる状態です。この性質があって初めて「関数を関数に渡す」という高階関数の操作が可能になります。

実務では、コールバック関数(処理が終わったら呼び出してほしい関数)や、配列操作のmapfilterreduceといった形で日常的に登場します。コードの重複を減らし、処理の「骨格」と「中身」を分離できるため、保守しやすいソフトウェア設計の武器になります。


高階関数の3つのパターン

パターン説明具体的な例
関数を引数に取る処理の一部を外から差し込めるarray.map(fn) / setTimeout(fn, ms)
関数を返すカスタム関数を動的に生成できる乗算器ファクトリ multiply(n)
両方行う受け取って変換・合成して返すcompose(f, g) などの関数合成

代表的な高階関数:map / filter / reduce

【配列: [1, 2, 3, 4, 5]】

 map(x => x * 2)     → [2, 4, 6, 8, 10]    ← 全要素を変換
 filter(x => x > 2)  → [3, 4, 5]            ← 条件に合うものだけ残す
 reduce((a,b)=>a+b)  → 15                   ← 全要素を1つの値にまとめる

これら3つは「どう変換・抽出・集約するか」というロジックを外から渡すことで、繰り返し処理のパターンを共通化しています。

覚え方:「関数を食べる関数」

高階関数は「関数を食べる(受け取る)か、関数を産む(返す)か、その両方」と覚えましょう。「高階(こうかい)」の「高い階層」= 関数の上に立って関数を操る、とイメージするとわかりやすいです。


歴史と背景

  • 1930年代 — 数学者アロンゾ・チャーチがラムダ計算(λ計算)を提唱。「関数を値として扱う」という数学的基盤が生まれる
  • 1958年LISP(リスト処理言語)が誕生。関数を第一級オブジェクトとして扱う最初期のプログラミング言語となり、高階関数の実装が始まる
  • 1970年代〜80年代ML・Haskellなど関数型言語が整備され、mapfilterfoldが標準的な道具として確立
  • 2000年代 — JavaScriptの普及により、Webフロントエンドでコールバック関数・高階関数が爆発的に広まる
  • 2010年代以降 — Python・Javaラムダ式、Stream API)・C#(LINQ)・SwiftKotlinなど主流言語が一斉に高階関数・ラムダ構文を取り込み、現代プログラミングの標準技法として定着

高階関数 vs 普通の関数 ─ どう違う?

普通の関数 引数: 値(数値・文字列など) 戻り値: 値(数値・文字列など) 例: add(2, 3) → 5 function add(a, b) { return a + b; } ※ 関数を渡したり 返したりしない 高階関数 引数: 値 + 関数も受け取れる 戻り値: 値 + 関数も返せる 例: [1,2,3].map(x => x*2) function apply(fn, val) { return fn(val); } ※ fn という「関数」を 引数に受け取っている 拡張

実務でよく見る高階関数の使い方

// ❶ コールバック:処理が終わったら呼んでほしい関数を渡す
setTimeout(() => console.log("3秒後に実行"), 3000);

// ❷ map:全商品の価格に税率をかける
const prices = [100, 200, 300];
const taxed = prices.map(p => p * 1.1); // [110, 220, 330]

// ❸ filter:在庫ありの商品だけ絞り込む
const items = [{name:"A", stock:0}, {name:"B", stock:5}];
const inStock = items.filter(item => item.stock > 0);

// ❹ 関数を返す:消費税率をカスタマイズできる計算機を生成
function taxCalculator(rate) {
  return (price) => price * (1 + rate);
}
const calc10 = taxCalculator(0.1);
console.log(calc10(1000)); // 1100

言語別サポート状況

言語高階関数のサポート代表的な構文
JavaScript / TypeScript◎ ネイティブ対応array.map(fn) / アロー関数
Python◎ ネイティブ対応map(fn, list) / lambda
Java○ Java 8以降Stream API / Function<T,R>
C#○ ネイティブ対応LINQ / Func<T> デリゲート
Go△ 関数は値だが簡易的関数型を変数に代入
Haskell◎ 言語設計の中核カリー化・部分適用が標準

関連用語