将错误调整为除外

Ele*_*fee 14 haskell exception-handling

现在已经Control.Monad.Error被弃用,并且Control.Monad.Except占据了至高无上的地位,很多在线资源都没有赶上,并且仍然展示了如何使用的例子Error.

那我该如何转向

instance Error MyError where
  noMsg  = ...
  strMsg = ...
Run Code Online (Sandbox Code Playgroud)

用什么东西Except.只是替换ErrorExcept没有按Except预期的其他类型参数工作

我知道那些确切的方法不存在Except,那么还有什么选择呢?

Ørj*_*sen 13

简短的回答是:Error什么都不替换,替换ErrorTExceptT,只要你不使用Errors方法fail(现在有不同的定义),或者do表示法中的模式匹配失败,事情就应该继续工作.

Control.Monad.Error系统和新Control.Monad.Except系统之间的本质区别在于新系统对错误/异常类型没有类别限制.

结果发现,多态地使用任何错误/异常类型的能力比定制字符串错误消息的转换有点hacky能力更有用.

所以班级Error已经消失了.

作为副作用,fail对于ExceptT现在是从底层单子解除.这也会改变do符号表示失败模式的效果.

旧的定义是:

fail msg = ErrorT $ return (Left (strMsg msg))
Run Code Online (Sandbox Code Playgroud)

我认为相当于

fail msg = throwError (strMsg msg)
Run Code Online (Sandbox Code Playgroud)

如果您仍然需要此行为,则可以改为使用

throwError yourIntendedErrorValue
Run Code Online (Sandbox Code Playgroud)

(throwE如果您使用transformers(即Control.Monad.Trans.Except)而不是使用,则可以使用mtl.)

do模式匹配失败将适用于类似的事情

do
    Just x <- myErrorTAction
    ...
Run Code Online (Sandbox Code Playgroud)

当动作实际返回时Nothing.这更尴尬,但你可以用一个明确的case匹配替换它(基本上是贬低它):

do
    y <- myErrorTAction
    case y of
        Nothing -> throwE ...
        Just x -> do
           ...
Run Code Online (Sandbox Code Playgroud)

@DanielWagner建议以下内容以避免额外缩进:

do
    x <- myErrorTAction >>= maybe (throwError ...) return
    ...
Run Code Online (Sandbox Code Playgroud)

删除Error也消除了命名不一致的需要Control.Monad.Error:大多数变换器遵循变换器SomethingT名称的规则,并且Something是类型的别名SomethingT ... Identity.老人ErrorT打破了,因为这个Error班级用于完全不同的东西.

在新系统中Except e = ExceptT e Identity,与其他变压器一样.