使错误适应 Except
Adapting Error to Except
现在 Control.Monad.Error
已被弃用,Control.Monad.Except
占据主导地位,很多在线资源都没有跟上,仍然展示了如何使用 Error
的示例。
那我要怎么转
instance Error MyError where
noMsg = ...
strMsg = ...
使用 Except
转换成某种东西。只是将 Error
替换为 Except
并没有起作用,因为 Except
需要额外的类型参数
我知道 Except
中不存在那些确切的方法,那么有什么替代方法?
简短的回答是:将 Error
完全替换为任何内容,将 ErrorT
替换为 ExceptT
,只要您不使用 [=16],事情就会继续进行=]s 方法,fail
(现在有不同的定义),或在 do
表示法中失败的模式匹配。
旧Control.Monad.Error
系统与新Control.Monad.Except
系统的本质区别是新系统对没有class限制error/exception 类型。
我们发现,以多态方式使用任何 error/exception 类型的能力比自定义字符串错误消息转换的有点老套的能力更有用。
所以 class Error
就这样消失了。
作为副作用,ExceptT
的 fail
现在已从底层 monad 中移除。这也改变了 do
表示法中失败模式的影响。
旧的定义是:
fail msg = ErrorT $ return (Left (strMsg msg))
我认为相当于
fail msg = throwError (strMsg msg)
如果您仍然需要这种行为,您可以改用
throwError yourIntendedErrorValue
(如果您使用 transformers
(即 Control.Monad.Trans.Except
)而不是 mtl
,则 throwE
会起作用。)
旧的 do
模式匹配失败将适用于
do
Just x <- myErrorTAction
...
实际操作时returnsNothing
。这更尴尬,但你可以,例如将其替换为明确的 case
匹配项(本质上是对其进行脱糖):
do
y <- myErrorTAction
case y of
Nothing -> throwE ...
Just x -> do
...
@DanielWagner 建议采用以下方法避免额外缩进:
do
x <- myErrorTAction >>= maybe (throwError ...) return
...
Error
的删除也消除了 Control.Monad.Error
的命名不一致的需要:大多数转换器遵循 SomethingT
是转换器名称的规则,并且 Something
是 SomethingT ... Identity
的类型别名。旧的 ErrorT
打破了这一点,因为 Error
class 用于完全不同的东西。
在新系统中,Except e = ExceptT e Identity
,与其他变形金刚一样。
现在 Control.Monad.Error
已被弃用,Control.Monad.Except
占据主导地位,很多在线资源都没有跟上,仍然展示了如何使用 Error
的示例。
那我要怎么转
instance Error MyError where
noMsg = ...
strMsg = ...
使用 Except
转换成某种东西。只是将 Error
替换为 Except
并没有起作用,因为 Except
需要额外的类型参数
我知道 Except
中不存在那些确切的方法,那么有什么替代方法?
简短的回答是:将 Error
完全替换为任何内容,将 ErrorT
替换为 ExceptT
,只要您不使用 [=16],事情就会继续进行=]s 方法,fail
(现在有不同的定义),或在 do
表示法中失败的模式匹配。
旧Control.Monad.Error
系统与新Control.Monad.Except
系统的本质区别是新系统对没有class限制error/exception 类型。
我们发现,以多态方式使用任何 error/exception 类型的能力比自定义字符串错误消息转换的有点老套的能力更有用。
所以 class Error
就这样消失了。
作为副作用,ExceptT
的 fail
现在已从底层 monad 中移除。这也改变了 do
表示法中失败模式的影响。
旧的定义是:
fail msg = ErrorT $ return (Left (strMsg msg))
我认为相当于
fail msg = throwError (strMsg msg)
如果您仍然需要这种行为,您可以改用
throwError yourIntendedErrorValue
(如果您使用 transformers
(即 Control.Monad.Trans.Except
)而不是 mtl
,则 throwE
会起作用。)
旧的 do
模式匹配失败将适用于
do
Just x <- myErrorTAction
...
实际操作时returnsNothing
。这更尴尬,但你可以,例如将其替换为明确的 case
匹配项(本质上是对其进行脱糖):
do
y <- myErrorTAction
case y of
Nothing -> throwE ...
Just x -> do
...
@DanielWagner 建议采用以下方法避免额外缩进:
do
x <- myErrorTAction >>= maybe (throwError ...) return
...
Error
的删除也消除了 Control.Monad.Error
的命名不一致的需要:大多数转换器遵循 SomethingT
是转换器名称的规则,并且 Something
是 SomethingT ... Identity
的类型别名。旧的 ErrorT
打破了这一点,因为 Error
class 用于完全不同的东西。
在新系统中,Except e = ExceptT e Identity
,与其他变形金刚一样。