模式匹配语法中的歧义

Aka*_*ash 17 f#

我今天在F#模式匹配语法中遇到了一个奇怪的问题,这可能导致穷举检查中的明显失败.

type Thing =
    | This
    | That
    | Other

let useThing =
    function
    | This -> "A"
    | That -> "A"
    | That -> "B" // compiler complains
    | Other -> "B"
Run Code Online (Sandbox Code Playgroud)

在上面的场景中,编译器有用地告诉我第二条规则永远不会匹配.但是,如果我试图使代码更紧凑并且已经编写了

let useThing =
    function
    | This | That -> "A"
    | That | Other -> "B"    
Run Code Online (Sandbox Code Playgroud)

我没有得到编译器的任何帮助.我认为原因是它| This | That ->. "A"不是一个快捷方式| This -> "A" | That -> "A",即使它看起来非常像(并且我已经看到许多代码样本将其视为这样).相反,根据我的发现,管道符号既可用于分隔单个模式,也可用作OR模式.

对于大多数DU而言,这不是一个大问题,但是在将具有大量案例的DU映射到具有少量案例的另一个DU时遇到了问题.我尝试使用快捷语法导致了一个错误.

所以我的问题是:

  1. 我的解释是否正确?
  2. 除了在单独的行上列出每个模式之外,还有其他解决方法吗?

Fri*_*etz 8

你的解释是正确的.

通过省略第一个This和第二个的动作,That您将创建一个OR模式,如模式匹配(F#)中所述

对我来说,这也有点令人困惑,因为逻辑'或'是|| 在F#中.虽然在格式化中很容易看到第一个条形new alternative和第二个条形,or但它变得不那么明显了

let useThing =
    function
    | This
    | That -> "A"
    | That
    | Other -> "B"
Run Code Online (Sandbox Code Playgroud)

然而,编译器可以判断整个模式是否无用,但它无法简化模式. That | Other具有有效匹配,因此编译器不会考虑冗余.
您可以想到更多涉及的模式,如果可以省略部件或如何简化它们,那么根本不清楚.