将错误调整为

时间:2015-07-04 13:54:07

标签: haskell exception-handling

既然Control.Monad.Error已被弃用,并且Control.Monad.Except占据了至高无上的地位,很多在线资源都无法实现,并且仍会展示如何使用Error的示例。< / p>

那我该如何转向

instance Error MyError where
  noMsg  = ...
  strMsg = ...

使用Except进行某些操作。只需将Error替换为Except并不起作为Except需要其他类型参数

我知道Except中不存在那些确切的方法,那么替代方法是什么?

1 个答案:

答案 0 :(得分:11)

简短回答是:完全取代Error,将ErrorT替换为ExceptT,只要您不使用Error,事情就会继续有效s方法,fail(现在有不同的定义),或do符号中的失败模式匹配。

Control.Monad.Error系统与新Control.Monad.Except系统之间的本质区别在于新系统对错误/异常类型强加 no 类限制。

我们发现,根据多态,使用任何错误/异常类型的能力比自定义字符串错误消息转换的有点hacky能力更有用。

所以班级Error已经消失了。

作为副作用,fail的{​​{1}}现在已从基础monad中解除。这也会改变ExceptT表示法中失败模式的影响。

旧的定义是:

do

我认为相当于

fail msg = ErrorT $ return (Left (strMsg msg))

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

fail msg = throwError (strMsg msg)

throwError yourIntendedErrorValue 可以使用throwE(即transformers)而不是Control.Monad.Trans.Except

mtl模式匹配失败将适用于

之类的内容
do

当动作实际返回do Just x <- myErrorTAction ... 时。这更尴尬,但你可以,例如将其替换为明确的Nothing匹配(基本上是让它失望):

case

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

do
    y <- myErrorTAction
    case y of
        Nothing -> throwE ...
        Just x -> do
           ...

删除do x <- myErrorTAction >>= maybe (throwError ...) return ... 也消除了Error命名不一致的需要:大多数变换器遵循Control.Monad.Error是变换器名称的规则,{{1 }}是SomethingT的类型别名。旧的Something打破了这一点,因为SomethingT ... Identity类被用于完全不同的东西。

在新系统ErrorT中,与其他变形金刚一样。