Cons演算子を使用したパターンマッチングの理解
-
27-09-2019 - |
質問
「プログラミングF#」では、このようなパターンマッチングに出くわしました(少し簡略化しました):
let rec len list =
match list with
| [] -> 0
| [_] -> 1
| head :: tail -> 1 + len tail;;
実際には、最後の一致がリストの頭と尾を認識することを理解しています。概念的には、なぜそれが機能するのかわかりません。私の知る限りでは, ::リストの先頭位置に値を追加するcons演算子ですが、ここで演算子として使用されているようには見えません。これをリストの「特別な構文」として理解する必要がありますか ::コンテキストに応じて演算子または「一致パターン」として解釈されますか?または、他の演算子を使用して、リスト以外の型にも同じアイデアを拡張できますか?
解決
ブライアンの答えに加えて、注目に値するいくつかの点があります。ザ- h::t
構文は、演算子として両方を使用することができます と パターンとして:
let l = 1::2::[] // As an operator
match l with x::xs -> 1 | [] -> 0 // As a pattern
これは、他の演算子(例えば、)のために、それは少し特別な構造であることを意味します +
)パターンとして使用することはできません(結果を演算子の引数に分解するため)-明らかに、 +
, 、これはあいまいです。
また、パターン [_]
これはネストされたパターンの例であるため、興味深いものです。それは構成します:
_
-任意の値に一致し、任意のシンボルをバインドしないアンダースコアパターン[ <pattern> ]
-単一の要素を持つリストと一致し、ネストされたリストの要素と一致する単一要素リストパターン<pattern>
.
あなたも書くことができます match 1::[] with | [x] -> x
これは、単一の要素の値(この場合は1)を返します。
他のヒント
これはリストの特別な構文です。したがって、list
タイプは、識別された共用体と考えることができます。
ジェネラコディセタグプレ
ただし、Nil
を[]
にし、Cons(h,t)
をh::t
にする特別な構文があります。次に、識別された共用体での通常のパターンマッチングです。それは役に立ちますか?
(このブログエントリも参照してください。)
フォーマッターまたは正式にpattern
として使用され、「リスト」は3つのパターンに一致します。
[]はリストが空であることを意味します
[_]は、リストに1つの要素があることを意味します。要素が何であるかは気にしないので、そこに_を入力するだけで、[a]を使用することもできます。
head :: tailは、リストにヘッドとテールの2つの部分があることを意味します。
F#パターンマッチングは、if thenelse構造の強力なものと見なすことができます。