match 式

match 式により、式と一連のパターンとの比較に基づいて分岐が制御されます。

構文

// Match expression.
match test-expression with
| pattern1 [ when condition ] -> result-expression1
| pattern2 [ when condition ] -> result-expression2
| ...

// Pattern matching function.
function
| pattern1 [ when condition ] -> result-expression1
| pattern2 [ when condition ] -> result-expression2
| ...

解説

パターン マッチング式を使用すると、テスト式と一連のパターンとの比較に基づいて、複雑な分岐が可能になります。 match 式では、各パターンと test-expression が比較され、一致が見つかると、対応する result-expression が評価され、結果の値が match 式の値として返されます。

前の構文で示されているパターン マッチング関数は、パターン マッチングが引数ですぐに実行されるラムダ式です。 前の構文で示されているパターン マッチング関数は、以下と同じです。

fun arg ->
    match arg with
    | pattern1 [ when condition ] -> result-expression1
    | pattern2 [ when condition ] -> result-expression2
    | ...

ラムダ式について詳しくは、「ラムダ式: fun キーワード」を参照してください。

一連のパターン全体で、入力変数のすべての一致候補をカバーする必要があります。 多くの場合、それより前で一致していない入力値と一致させるために、最後のパターンとしてワイルドカード パターン (_) を使用します。

次のコードは、match 式が使用されるいくつかの方法を示しています。 使用可能なすべてのパターンの参照と例については、「パターン マッチング」を参照してください。

let list1 = [ 1; 5; 100; 450; 788 ]

// Pattern matching by using the cons pattern and a list
// pattern that tests for an empty list.
let rec printList listx =
    match listx with
    | head :: tail -> printf "%d " head; printList tail
    | [] -> printfn ""

printList list1

// Pattern matching with multiple alternatives on the same line.
let filter123 x =
    match x with
    | 1 | 2 | 3 -> printfn "Found 1, 2, or 3!"
    | a -> printfn "%d" a

// The same function written with the pattern matching
// function syntax.
let filterNumbers =
    function | 1 | 2 | 3 -> printfn "Found 1, 2, or 3!"
             | a -> printfn "%d" a

パターンでのガード

when 句を使用して、変数がパターンに一致するために満たす必要のある追加条件を指定できます。 このような句をガードと呼びます。 when キーワードに続く式は、そのガードに関連付けられているパターンと一致しない限り評価されません。

次の例は、変数パターンの数値範囲を指定するためのガードの使用例を示しています。 複数の条件は、ブール演算子を使用することによって結合されていることに注意してください。

let rangeTest testValue mid size =
    match testValue with
    | var1 when var1 >= mid - size/2 && var1 <= mid + size/2 -> printfn "The test value is in range."
    | _ -> printfn "The test value is out of range."

rangeTest 10 20 5
rangeTest 10 20 10
rangeTest 10 20 40

リテラル以外の値はパターンで使用できないため、入力の一部を値と比較する必要がある場合は、when 句を使用する必要があります。 これを次のコードに示します。

// This example uses patterns that have when guards.
let detectValue point target =
    match point with
    | (a, b) when a = target && b = target -> printfn "Both values match target %d." target
    | (a, b) when a = target -> printfn "First value matched target in (%d, %d)" target b
    | (a, b) when b = target -> printfn "Second value matched target in (%d, %d)" a target
    | _ -> printfn "Neither value matches target."
detectValue (0, 0) 0
detectValue (1, 0) 0
detectValue (0, 10) 0
detectValue (10, 15) 0

和集合パターンがガードでカバーされている場合、ガードは、最後のものだけでなく、すべてのパターンに適用されます。 たとえば、次のコードにおいて、ガード when a > 41A aB a の両方に適用されます。

type Union =
    | A of int
    | B of int

let foo() =
    let test = A 42
    match test with
    | A a
    | B a when a > 41 -> a // the guard applies to both patterns
    | _ -> 1

foo() // returns 42

関連項目