haskell - 带有单子(monad)守卫的详尽案例

标签 haskell pattern-matching monads

我有一个 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/

相关文章:

haskell - 将 Maybe 元素列表从 Just [[x1],[x2]] 展平为 Just [x1,x2]

Haskell 的 Agda 中的 Arrow-Class 和 Agda 中的 ->

Scala:两个相等类型之间的类型方差和模式匹配

scala - scala 字节码中不必要的加载和存储指令

unix - 使用 awk 或 sed 删除模式之前的所有内容,包括模式

haskell - Writer Monad 是否保证右关联连接?

haskell 单子(monad) : IO [Double] to [IO Double]

haskell - 使用折叠实现 takeWhile

haskell - Haskell 中的随机模拟教程

function - 描述非类型特定的 Haskell 函数的类型签名的方法是什么?