3

同じオプションを使用して 2 つのアクティブなパターンを作成できないことに気付きましたが、類似したオプションを使用して 2 つのアクティブなパターンを警告なしで作成できます。

let (|A|B|C|) c =
   if (c = 'a') then A
   else if (c = 'b') then B
   else C

let (|A|B|D|) c =
   if (c = '1') then A
   else if (c = '2') then B
   else D

したがって、この方法で一致させる場合:

let check myvar =
  match myvar with 
    | A -> printf "match A\n"
    | n -> printf "match other %A\n" n

これが起こります:

check 'x' // match other 'x'  
check 'a' // match other 'a'     !!
check '1' // match A

(|Direct|Indirect|)たとえば、 (route) と(|Alternating|Direct|)(current) のように異なるセマンティック コンテキストが原因で、同じ単語が異なるパターンで表示される可能性がある状況で、既存のアクティブなパターン オプションを誤って上書きしてしまうことを少し心配しています。

どうすればこの状況を回避できますか?

4

2 に答える 2

7

アクティブなパターンのシャドーイングが難しい場合があることに同意しますが、F# の識別された共用体ケースとレコード ラベルで発生するのと同じ問題です。型の場合は、あいまいさを解決するために型名をいつでも含めることができます。

アクティブなパターンの場合、それらをモジュールに入れることができます - たとえばPat1and Pat2:

module Pat1 =
 let (|A|B|C|) c =
   if (c = 'a') then A
   else if (c = 'b') then B
   else C

module Pat2 =
 let (|A|B|D|) c =
   if (c = '1') then A
   else if (c = '2') then B
   else D

したがって、コードでは、Pat1.Aまたはのような完全修飾名を使用できPat2.Aます。

let check myvar =
  match myvar with 
  | Pat1.A -> printf "match A\n"
  | n -> printf "match other %A\n" n
于 2014-11-14T15:15:43.883 に答える
3

あなたの懸念は、アクティブなパターンだけでなく、シャドウイング全般に当てはまると思います。パラメータと戻り値が同じで、ケース名が重複している 2 つのアクティブなパターンをどのくらいの頻度で定義しますか? 一般に、型は潜在的なシャドウイングの問題を軽減します。これらの線に沿って、型注釈はあなたの友達です。

于 2014-11-14T15:12:28.277 に答える