パターンマッチ2

パターンマッチ1で紹介した基本的な定数へのパターンマッチの他に F#では様々なパターンマッチを記述出来ます。 ここでは、残りのパターンについて説明します

判別共用体パターン(Discriminated Union Patterns)

OCamlではヴァリアントと呼んでいるもので C言語ではunionに相当するパターンです。 各々の型名の先頭の文字は大文字である必要があります。
Discriminated Union Pattern
type VARIABLE =
    | INT of int
    | FLOAT of float;;
let var1 = INT(10);;
let var2 = FLOAT(20.);;

let doubleexp var =
    match var with
        | INT(x) -> x * 2
        | FLOAT(x) -> int (x * 2.);;
printfn "%d" <| doubleexp var1;;
printfn "%d" <| doubleexp var2;;
これの賢い使い方として、 最後にワイルドカードパターンにあたるものを置かない というやり方があります。 そうすれば、網羅していないパターンをコンパイラが教えてくれるため バグが起きる可能性が減ります。 例えば上の例であれば、INTとFLOATのケースだけパターンマッチすれば ワイルドカードパターンを置く必要がないのは明らかです

Literal Patterns

[<Literal>]属性をつけると letで定義した値をパターンにすることができます。 これを名前付きリテラルと呼びます。 名前つきリテラルは、必ず大文字で始める必要があります。参考 以下の例では、通常はOminous変数が全てのパターンにマッチするため _の行はパターンマッチしないはずですが Ominous変数にはLiteral属性がついているため きちんとパターンマッチします。 サンプルの例を本当なら(13,"Fri")としたかったのですが タプルにはまだ対応していないようです(バージョン6.0時点)
Literal Pattern
[<Literal>]
let Ominous = 13;;

let isJasonSafetyFriday day =
    match day with
        | Ominous -> false
        | _ -> true in
printfn "%b" <| isJasonSafetyFriday 13

As patterns

パターンに別名をつけるパターンです。 パターン -> 式のような形で、 パターンが複合型かつ、式で何回か使い回すような場合に使うと 記述がすっきりします。 以下、F# 4.1 spec 7.3に載ってた例そのまま
AsPattern
let t1 = (1,2)
let (x,y) as t2 = t1
printfn "%d-%d-%A" x y t2  // 1-2-(1,2)

Union patterns

複数のパターンに一度にマッチさせるパターンです。 以下はフィボナッチ数の定義に用いた例です。 C言語のswitch文でいえばbreakを書かずに複数のcase文を並べているのに相当します。
UnionPattern
let rec fib n =
    match n with
        | 1 | 2 -> 1
        | x -> (fib <| n - 1) + (fib <| n - 2) in
        print_int <| fib 10;;