我有一个 case
表达式,其中包含相对较多的模式:
case x of
... -> ...
... -> ...
... -> ...
... -> ...
...
_ -> ...
其中一个箱子有 guard :
case x of
... -> ...
... -> ...
... | condition -> ...
-- If condition is false, fall through to “Rest”.
-- Rest:
... -> ...
... -> ...
...
_ -> ...
如果守卫不匹配,我们就会继续处理剩下的情况,没问题。但现在我需要单一地测试条件,所以我这样做:
case x of
... -> ...
... -> ...
... -> do
condition <- action
if condition
then ...
else ... -- How to fall through?
-- Rest:
... -> ...
... -> ...
...
_ -> ...
但是,我想我犯了一个错误。似乎没有办法让 else
分支继续处理剩余的情况,而不复制这些分支或将它们分解到函数中。无论哪种方式都会扰乱详尽性检查:如果我想在防护后面添加一个案例,编译器不知道匹配是否详尽。
如何更改此函数,或参数化/包装数据类型,以使用单子(monad)防护进行详尽检查?
最佳答案
我不喜欢下面的方法,但无论如何我都会分享它:
fix (\proceed b -> case (x, y, b) of
(Foo ..., Foo ..., False) -> ...
(Bar ..., Bar ..., False) -> do
condition <- action
if condition
then ...
else proceed True
(Baz ..., ..., _) -> ...
(Var ..., ..., _) -> ...
...
) False
附加标志b
最初为假,因此所有分支都会被考虑。一旦我们继续
,我们将其设置为true,以便跳过第一个分支。
可能会也可能不会静态地发现详尽的内容,具体取决于实际模式。
关于haskell - 带有单子(monad)守卫的详尽案例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38442963/