在OCaml中,我习惯于编写如下代码:
let combine o1 o2 = match o1, o2 with
| Valid, Invalid | Invalid, Valid -> Invalid
| _ -> ...
Run Code Online (Sandbox Code Playgroud)
我没有找到在Haskell中编写或模式的方法,我真的很想念它.有没有人有办法解决吗?
ben*_*ofs 19
我不认为这在haskell中是可能的.但是,有一些替代方案:
where绑定来排除公共代码这在您的示例中没有多大意义,但如果您在case表达式的主体中有更多代码,那么它很有用:
combine o1 o2 = case (o1,o2) of
(Valid, Invalid) -> handleInvalid
(Invalid, Valid) -> handleInvalid
...
where
handleInvalid = ...
Run Code Online (Sandbox Code Playgroud)
根据我的经验,你不想经常想要在一个模式匹配中使用两个或模式.在这种情况下,您可以处理所有"好"的情况,并使用外卡模式:
combine o1 o2 = case (o1,o2) of
(Valid, Valid) -> Valid -- This is the only valid case
_ -> Invalid -- All other cases are invalid
Run Code Online (Sandbox Code Playgroud)
这样做的缺点是它绕过穷举检查程序,并且您不能将通配符模式用于其他目的.
==如果要匹配的类型是类似枚举的类型,则可以考虑创建Eq实例.然后你可以使用==和||匹配一个后卫中的多个构造函数:
combine o1 o2
| o1 == Invalid && o2 == Valid || o1 == Valid && o2 == Invalid = Invalid
| ...
Run Code Online (Sandbox Code Playgroud)
我同意这看起来不太好,它也有绕过穷举检查器的缺点,并且如果模式重叠则不会警告你,所以我不推荐它.
你可以使用这个quasiquoter http://hackage.haskell.org/package/OrPatterns.您的示例转换为:
let combine o1 o2 = case (o1, o2) of
[o| (Valid, Invalid) | (Invalid, Valid ) |] -> Invalid
_ -> ...
Run Code Online (Sandbox Code Playgroud)