Monadic后卫与Either

时间:2016-01-26 14:50:59

标签: haskell error-handling monads

我正在Haskell中实现一个类型检查器。 typechecking函数的主要签名是

judge :: Term -> StateT Context (Either String) Type

如果类型检查器失败,则返回lift $ Left "Something went wrong"

例如,一个用于检查if(伪)的函数:

judge (ExpIf test cons alt) =
  do
    testT <- judge test
    consT <- judge cons
    altT  <- judge alt
    guard $ consT == altT

最初这段代码的编写如下。

judge (ExpIf test cons alt) =
  do
    testT <- judge test
    consT <- judge cons
    altT  <- judge alt
    if altT == consT
       then return consT
       else lift $ Left "Types for cons and alt do not match"

鉴于此,如果我有一些警卫,我会有太多的压力,所以我改变了我的代码以使用guard s。

我知道guard表达式的返回类型为(),但在后台它使Either monad失败并返回Left ""。我有什么方法可以将一根绳子传给守卫吗?

judge (ExpIf test cons alt) =
  do
    testT <- judge test
    consT <- judge cons
    altT  <- judge alt
    guard (consT == altT) "types of cons and alt should match!"

1 个答案:

答案 0 :(得分:2)

您可以将when / unlessfailthrowError结合使用(取决于您的monad对这些类多态函数的特定实现)。例如,您可以写:

unless (consT == altT) (throwError "types of cons and alt should match")