合并 Haskell 中的多个案例

Merge multiple cases in Haskell

使用如下 case _ of 语法:

fun a b c =
    case (a, b, c) of
        (Just True, Just _, _) -> foo
        (Just True, _, Just _) -> foo
        _                      -> bar

能否合并前两个条件,避免重复foo

或者,是否有任何其他(更清晰的)方式来表达我想要 运行 foo 当且仅当 aJust True 并且 bc 不是 Nothing?

你可以这样做:

fun a b c = case (a, b <|> c) of
    (Just True, Just _) -> foo
    _ -> bar

当然,那只是在 (<|>) 中隐藏了额外的匹配项,但你得花点时间付钱给吹笛者。

如果 bc 的类型不同,您可以使用错误的名称 void.

不知道这看起来是否 更干净 但你也可以使用好朋友 if:

fun a b c =
   if a == Just True && (isJust b || isJust c) 
      then foo
      else bar

或使用守卫

fun a b c =
   case a of
       Just True | isJust b || isJust c -> foo
       _ -> bar

无大小写:

fun (Just True) b c | isJust b || isJust c = foo
fun _ _ _ = bar

所有人都在使用 isJust,正如 Daniel 指出的那样,它们也会给吹笛者它应得的(模式匹配)。

让我用一个“无聊”的替代方案来补充其他答案:

fun a b c = let
   foo' = foo
   in case (a, b, c) of
      (Just True, Just _, _) -> foo'
      (Just True, _, Just _) -> foo'
      _                      -> bar

这可能会或可能不会回答预期的问题,具体取决于实际目标。

如果目标是避免在case中写两个模式,这当然达不到目标。

如果相反,目标是避免重复 foo,这可能是一个非常长的表达式(例如,在某些 monad 中的长 do 块),这通过给出一个短的来满足目标长表达式的名称。