パターンマッチング

関数型プログラミングにおける**パターンマッチング(Pattern Matching)**は、データ構造の構造的な分解と、それに応じた制御分岐を行うための非常に強力な手法です。これは、伝統的な命令型言語におけるifswitchといった制御構文の代替・拡張として機能しますが、より表現力豊かで安全な書き方が可能になります。


概要

パターンマッチングは、ある値が特定の**パターン(構造)**と一致するかどうかを判定し、一致した場合にその中の値を取り出して処理を行う構文です。主に以下のような場面で使われます:

  • リストやタプル、代数的データ型(Algebraic Data Types)の構造分解

  • 値の分類と条件分岐

  • 再帰処理における基底部と再帰部の分離


主な機能と特徴

1. 構造的分解(Destructuring)

パターンマッチングでは、データ構造(例えばリストやタプル)をその形に応じて分解できます。

例(Haskell):

haskell
sumList :: [Int] -> Int sumList [] = 0 sumList (x:xs) = x + sumList xs

この例では、リストが空リスト[]か、x(先頭)とxs(残り)という形になっているかをパターンで判定しています。


2. 変数束縛

パターンマッチに成功すると、対応する部分を変数として束縛(バインド)できます。

例(OCaml):

ocaml
let (a, b) = (1, 2) in a + b (* 結果: 3 *)

3. ネストされたパターン

パターンはネストすることができ、複雑な構造の中から必要な部分を直接取り出せます。

例(Scala):

scala
expr match { case Add(Number(a), Number(b)) => a + b case _ => 0 }

4. ガード(Guard)式

パターンに追加の条件(真偽値)を与えることで、より柔軟な制御が可能です。

例(Haskell):

haskell
describe :: Int -> String describe x | x < 0 = "Negative" | x == 0 = "Zero" | otherwise = "Positive"

代表的な対応言語

パターンマッチングは多くの関数型言語で第一級の機能としてサポートされています。

  • Haskell

  • OCaml / F#

  • Scala

  • Elixir

  • Rust(関数型要素を持つシステム言語)

  • Erlang

近年では、関数型ではない言語(例:C#, Python, Swiftなど)でも限定的または拡張的にサポートされるようになってきています。


メリット

  • コードの可読性・保守性の向上:条件分岐と構造分解が一体化しており、意図が明確に伝わる。

  • 安全性の向上:コンパイラがすべてのケースを網羅しているかどうかチェックできる(exhaustiveness check)。

  • 冗長なコードの削減:手続き的な条件分岐よりも少ないコード量で複雑な分岐が記述できる。


まとめ

パターンマッチングは、関数型プログラミングにおいて制御構造としての役割と、データの抽出機構としての役割を兼ね備えた重要な機能です。従来のif-elseswitch文よりも宣言的かつ安全に分岐処理を記述でき、関数型らしい記述スタイルを支える中核的な技術です。

生成日:2025/06/01