F#で要素数が1つのリストをマッチさせる

F# で書かれているとあるコードを読んでいて、以下のようなコードが出てきてよくわからなかったので調べた。 a::[] の部分。

match some_list with
| a::[] -> printfn "%A" a
| b -> printfn "%A" b

まず ::Cons パターンというもので、パターンマッチにおいてリストを最初の要素と残りの要素に分解することができる。

let some_list = [1; 2; 3]

match some_list with
| a::b -> printfn "%A and %A" a b
| _ -> printfn ""

実行結果

1 and [2; 3]

これをふまえて最初のコード a::[] に戻ると、最初の要素を除くと空 ( [] ) になるリスト、つまり要素数が1のリストとマッチするということになる。

let some_list = [1] とすると a::[] にマッチし、出力結果は以下となる。

1

let some_list = [1; 2; 3] とすると b のほうにマッチし、出力結果は以下となる。

[1; 2; 3]

ちなみに、リストパターンを使っても同様に要素数1のリストにマッチさせることは可能。

match some_list with
| [a] -> printfn "%A" a    // 要素数1のリストにマッチ
| b -> printfn "%A" b      // 要素数1以外のリストにマッチ