通常の関数をパターンとして使用できれば、次のような簡単なアクティブパターンを作成する必要がなくなります。
let (|NotEmpty|_|) s = Seq.tryPick Some s
そして、仮想的に、許可します
let s = seq []
match s with
| Seq.tryPick Some -> ...
| _ -> //empty
これにより、関数がより再利用可能になり、マッチングで使用する「パターン化」関数が不要になります。
let f x = if x then Some() else None
let (|F|_|) = f
アクティブなパターンは関数として呼び出される可能性があることを知っているので、前の例はパターンのみを定義することで簡略化できます。ただし、特別なパターン構文を使用しないと、これが簡単になります。
特別な構文の理由は何ですか?
編集
以下では、アクティブなパターンがリテラルをシャドウイングします。
[<Literal>]
let X = 1
let (|X|_|) x = if x = 0 then Some() else None
match 0 with //returns true
| X -> true
| _ -> false
パターン内の関数呼び出しでも機能しないのはなぜですか?
編集2
あいまいなシナリオを見つけました
let zero n = if n = 0 then Some() else None
match 0 with
| zero -> //function call or capture?
これは、私の考えでは、アクティブなパターンが大文字で始まらなければならない理由を明確にします。これにより、意図が明確になり、前の例のようにシャドウイングが発生する可能性がはるかに低くなります。