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
...