haskell - 使自定义 monad 转换器成为 MonadError 的实例

标签 haskell monad-transformers

我想让我的 monad 转换器成为 MonadError 的一个实例如果转换后的 monad 是一个实例。基本上我希望我的变压器表现得像内置变压器一样,例如有一个 MonadError StateT 的实例:

MonadError e m => MonadError e (StateT s m)

我尝试这样做:
instance MonadError e m => MonadError e (MyMonadT m)

但是 GHC 开始提示不可判定的实例,显然 MTL 库只是启用不可判定的实例,但是有什么办法可以避免呢?或者在这种情况下可以,并且不会引起任何问题?

最佳答案

这基本上没问题。 UndecidableInstances是不是都那么可怕;这意味着编译器可以进入无限循环,而不是找到一个实例。这听起来很糟糕,直到您意识到 GHC 实际上对查找实例所需的步骤数有限制;除非你写了一个错误的实例,否则什么都不会出错,而且你得到的错误消息通常会很明显地说明哪里出了问题。1 当然,它没有像 OverlappingInstances 这样的东西那么可怕。 (或更糟的是, IncoherentInstances )。

它提示的原因是因为MonadError具有来自 m 的函数依赖至 e .那意味着选择m决定什么e必须是;即每个 m仅与一个 e 相关联.对此(覆盖条件)的检查是保守的,因此很容易遇到这样的问题,您尝试“向下递归”以指定 e .

1 它将列出它查看的所有实例,以尝试找到它正在寻找的实例,因此您会看到一堆重复的行。但通常你一开始就不会遇到这样的麻烦。

关于haskell - 使自定义 monad 转换器成为 MonadError 的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9951382/

相关文章:

scala - 在scalaz中将状态分层

haskell - 单子(monad)转换器上下文中的单子(monad)

haskell - lambda 表达式中的应用仿函数、非穷举模式?

haskell - 在 MaybeT ( StateT ) monadT 堆栈中调用纯函数以使错误传播的惯用方法是什么?

haskell - Cabal更新 "premature end of compressed stream"错误

haskell - 实例声明中的非法类型签名

haskell - 使用Operational Monad 实现的Writer 不会延迟工作

haskell - MonadBaseControl : how to lift simpleHTTP from Happstack?

haskell - 如何在 Haskell 中对空向量进行模式匹配?

list - 将两个输入的函数应用于列表中的每个元素 - Haskell