问题描述
使用 case _ of
这样的语法:
fun a b c =
case (a,b,c) of
(Just True,Just _,_) -> foo
(Just True,_,Just _) -> foo
_ -> bar
我可以合并前两个条件并避免重复 foo
吗?
或者,有没有其他(更干净的)方式来表达我想运行 foo
当且仅当 a
是 Just True
并且 b
或 {{ 1}} 不是 c
?
解决方法
你可以这样做:
fun a b c = case (a,b <|> c) of
(Just True,Just _) -> foo
_ -> bar
当然,这只是在 (<|>)
中隐藏了额外的匹配项,但您必须向吹笛者支付一些时间。
如果 b
和 c
的类型不同,您可以使它们使用名称错误的 void
。
让我用一个“无聊”的替代方案来补充其他答案:
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
块),则通过为长表达式。
不知道这是否看起来更干净,但您也可以使用老朋友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 指出的那样,它们也会给吹笛者它应得的(模式匹配)。