2017-10-09 1 views
2

ネガパターン:あなたが見ることができるように私は、次のコードは、( `IGNORECASEは、私が他の場所で定義されているアクティブなパターンです)持って試合

match myType with 
| {Field1 = IgnoreCase "invalid"} -> None 
| {Field2 = Some f2 
    Field3 = Some f3 
    Field4 = None | Some (0 | 1 | 2)} 
    -> Some (f2, f3) 
| _ -> None 

Field1はブラックリストに値を持っているとField4が値をホワイトリストに登録しました(そうField2を行いますそしてField3という意味ではSomeでなければなりません)。 IMHO同じケースですべてのチェックを行うことができれば、つまり、Field1 = IgnoreCase "invalid"の一致を他の一致と一緒に行うことができます。 Field1 <> IgnoreCase "invalid"ですが、その特定の例はコンパイルされません。私はガードについて知っていますが、それは元の解決策よりもきれいには見えません。

ガードを使用せずに値が他の値と一致しないという意味で「否定」(論理NOT)パターンのマッチングは可能ですか?そして、あなたはパターンマッチの内側にそれを使用することができます

let (|Not|_|) a b = if a <> b then Some() else None 

+1

f <> "無効"のときにガード:{{Field1 = f}を追加できます。 – Lee

+0

ありがとうございます。私は警備員について知っていて、その質問に言及することを意図していました。今更新されました。 – cmeeren

答えて

3

は、私の知る限りでは、これを行うには良い方法はありません。サポートされているパターンhereが表示され、否定の構文がないことを確認できます。そのような特徴の欠如の1つの理由は、それが他のパターンマッチング機能(例えば、否定的な文脈の中にasパターンを有する識別子を導入することを意味するもの)と奇妙にやりとりすることであるかもしれない。これは、アクティブパターンがパターン式ではなく値を受け取るため、アクティブパターンを介して一般的な方法で実装できるものではありません。

1

私はあなたがNotと呼ばれるアクティブパターンを定義することができ、この

let (|Check|_|) x = 
    let = { Field2 = f2; Field3 = f3; Field4 = f4 } 
    let check = 
     f4 = None || 
     f4 = Some 1 || 
     f4 = Some 2 || 
     f4 = Some 3 
    if check then Some (f2, f3) else None 

    match myType with 
    | {Field1 = "invalid"} -> None 
    | Check (x, y) -> Some (x, y) 
    | _ -> None 
2

のようなアクティブなパターンを使用することになり

match myType with 
| {Field1 = Not "invalid" 
    Field2 = Some f2 
    Field3 = Some f3 
    Field4 = None | Some (0 | 1 | 2)} 
    -> Some (f2, f3) 
| _ -> None 

このアクティブなパターンの制限は、それがリテラル値でなければならないということです。サブパターン。アクティブなパターンは、組み込みのパターンのように合成できません。あなたはそれではなく、識別子に新しい値を結合の値として識別子を渡すことができますので、しかし、それはまた、潜在的な利点です:

let invalidString = "invalid" 

match myType with 
| {Field1 = Not invalidString 
... 
+0

ありがとうございます。私は実際にそれをポストする前に試みました、そして、あなたが言うように、それはサブパターンでは動作しません。残念ながら私の場合はサブパターンが必要ですが、私はそれを質問に含めるとは思わなかった。私は今これを明確にするために質問を更新しました。 – cmeeren

+0

@cmeerenもう一度、 'let(| ToLower |)x =(x:string).ToLower()'を実行し、 'ToLower(無効ではない)'を実行することができます。あなたがパターンマッチングであまりにも多くをやろうとしていると思います。ガードまたは1つの特殊なアクティブパターンを使用してください:) – TheQuickBrownFox

関連する問題