Haskell 使错误适应除

Haskell 使错误适应除,haskell,exception-handling,Haskell,Exception Handling,既然Control.Monad.Error已被弃用,而且Control.Monad.Except占据了主导地位,许多在线资源还没有跟上,并且仍然展示了如何使用Error的示例 那么我该如何转身呢 instance Error MyError where noMsg = ... strMsg = ... 使用除之外的转换为其他内容。仅将Error替换为Except不起作用,因为Except需要额外的类型参数 我知道除了,这些确切的方法在中是不存在的,那么替代方法是什么呢?简短的回答是:

既然
Control.Monad.Error
已被弃用,而且
Control.Monad.Except
占据了主导地位,许多在线资源还没有跟上,并且仍然展示了如何使用
Error
的示例

那么我该如何转身呢

instance Error MyError where
  noMsg  = ...
  strMsg = ...
使用除之外的
转换为其他内容。仅将
Error
替换为
Except
不起作用,因为
Except
需要额外的类型参数


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

简短的回答是:什么都不替换
错误
,用
例外
替换
错误
,只要你不使用
错误
的方法,
失败
(现在有不同的定义),或者在
do
表示法中模式匹配失败

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

我们发现,多态性地使用任何错误/异常类型的能力比定制字符串错误消息的转换的有点粗糙的能力更有用

因此类
Error
就消失了

作为一个副作用,
ExceptT的
fail
现在从底层monad中取消。这也改变了
do
符号中失败模式的效果

旧的定义是:

fail msg = ErrorT $ return (Left (strMsg msg))
我认为这相当于

fail msg = throwError (strMsg msg)
如果您仍然需要此行为,可以使用

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

旧的
do
模式匹配失败将适用于以下情况

do
    Just x <- myErrorTAction
    ...
@DanielWagner建议如下避免额外缩进:

do
    x <- myErrorTAction >>= maybe (throwError ...) return
    ...
do
x>=可能(投掷者…)返回
...
删除
Error
还消除了在命名
Control.Monad.Error
had时不一致的必要性:大多数转换器遵循
SomethingT
是转换器名称的规则,而
SomethingT
somethingtt…Identity
的类型别名。旧的
Error
brok这是因为
Error
类用于完全不同的东西


在新系统中,
除了e=ExceptT e Identity
,就像其他变压器一样。

你说
故障
现在工作不一样了,你能举个例子说明它是如何工作的,以及需要编写多少等效代码吗?@ElectricCoffee我扩展了这一位。@rjanJohansen我偶尔使用的另一种模式:
do{y>=maybe(throwError…)return;..}
。避免了添加缩进级别,并且可以适应其他模式匹配;例如,
do{y_uuuoreturn v};..}
,它添加了一层缩进,但只是临时添加(即,如果要进行两个模式匹配,则不需要嵌套缩进)@DanielWagner谢谢,补充了第一部分。
do
    x <- myErrorTAction >>= maybe (throwError ...) return
    ...