F#避免活动模式覆盖

vto*_*ola 3 f# active-pattern

我注意到我无法使用相同的选项创建两个活动模式,但我可以有两个类似的模式没有任何警告:

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
Run Code Online (Sandbox Code Playgroud)

所以当这种方式匹配时:

let check myvar =
  match myvar with 
    | A -> printf "match A\n"
    | n -> printf "match other %A\n" n
Run Code Online (Sandbox Code Playgroud)

有时候是这样的:

check 'x' // match other 'x'  
check 'a' // match other 'a'     !!
check '1' // match A
Run Code Online (Sandbox Code Playgroud)

我有点担心无意中覆盖现有的活动模式选项,例如在相同的单词可能出现在不同模式中的情况下,因为不同的语义上下文,如(|Direct|Indirect|)(route)和(|Alternating|Direct|)(current).

我该如何避免这种情况?

Tom*_*cek 7

我同意对活动模式的遮蔽可能很棘手 - 尽管与F#中有区别的联合案例和记录标签的问题相同.对于类型,您始终可以包含类型名称以解决歧义.

在主动模式的情况下,你可以把它们放在模块-比如Pat1Pat2:

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
Run Code Online (Sandbox Code Playgroud)

所以,在你的代码,你就可以使用完全合格的名称一样Pat1.APat2.A:

let check myvar =
  match myvar with 
  | Pat1.A -> printf "match A\n"
  | n -> printf "match other %A\n" n
Run Code Online (Sandbox Code Playgroud)