gpt4 book ai didi

haskell - 避免声明无意义的错误实例

转载 作者:行者123 更新时间:2023-12-03 07:46:44 25 4
gpt4 key购买 nike

我有一个带有各种构造函数的自定义错误类型,我们称之为 MyError :

data MyError = ConditionA String | ConditionB String | ConditionC String

构造函数对错误类型进行分类,字符串提供更多详细信息。
我想在 Either 中使用我的错误类型monad,例如我想要一个函数
myFunction :: a -> Either MyError a

在 myFunction 中,我想使用 maybeToEither函数来自 Data.Either.Utils在 MissingH 中:
maybeToEither :: MonadError e m => e -> Maybe a -> m a

但是 ghc 告诉我,要做到这一点,我必须制作 MyErrorError 的实例.这似乎归结为 MonadError需要 m成为一个 monad,并且 Either e 的 monad 实例需要 Error e因为 fail :
instance (Error e) => Monad (Either e) where
return = Right
Left l >>= _ = Left l
Right r >>= k = k r
fail msg = Left (strMsg msg)

那我怎样才能避免做出无意义的 Error MyError 的实例声明?

我注意到 Database.MongoDB.Query 的作者他们的 Failure有同样的问题数据类型(它也有多个构造函数,因此没有合理的 Error 实例),他们的解决方案是处理 fail 的使用作为一个错误:
instance Error Failure where strMsg = error

这是我最好的选择吗?

最佳答案

不要为此使用 MissingH 库。只需使用与 GHC 编译器的每个版本捆绑在一起的基本库。除非您的代码明确要求使用 MonadError出于某种基本原因(来自 mtl 库),您可以避免使用该类,从而避免需要 Error您的错误类型的实例。

从基础库 4.3 版开始 - 2010 年 11 月发布 - 标准 Monad Either e 的实例不需要e成为 Error 的一个实例.所以你可以只包括这一行

import Control.Monad.Instances ()

在模块顶部,然后使用类型 Either MyError作为 Monad随意。

使用这个函数代替 MissingH 的 maybeToEither :
maybeToEither :: e -> Maybe a -> Either e a
maybeToEither e = maybe (Left e) Right

如果您确实需要 MonadError Either 的实例,您必须修改您的 MyError键入以提供 Error以某种人为的方式举例。有关如何执行此操作的一些更详细的建议,请参阅@jozefg 的答案。即便如此,我个人也不会为了像这样简单的事情而费心拉入整个 MissingH 库。

关于haskell - 避免声明无意义的错误实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19096642/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com