使MonadError的实例成为一个自定义Monad变换器 [英] Making a custom monad transformer an instance of MonadError
问题描述
如果转换后的monad是一个实例,我想让我的monad转换器成为 MonadError
的实例。基本上我希望我的变压器像内置变压器那样工作,例如,对于 StateT
,有一个 MonadError
:
MonadError em => MonadError e(StateT sm)
我试过这样做:
instance MonadError em => MonadError e(MyMonadT m)
但GHC开始抱怨不可判定的实例,显然MTL库只能启用不可判定实例,但有什么办法可以避免这种情况?或者在这种情况下可以,它不会引起任何问题吗?
这基本上没问题。 它抱怨的原因是因为 1 它会列出所有正在查找的实例并找到它正在查找的实例,因此您会看到一堆重复线条。但通常情况下,你甚至不会像这样遇到麻烦。 I want to make my monad transformer to be an instance of I tried doing this: But GHC started complaining about undecidable instances, apparently the MTL library just enables undecidable instances, but is there any way to avoid that? Or it is OK in this case and it won't cause any problems? This is basically fine. The reason it complains is because 1 It'll list all the instances it looked at to try and find the one it's looking for, so you'll see a bunch of repeating lines. But usually you won't even run into trouble like this in the first place. 这篇关于使MonadError的实例成为一个自定义Monad变换器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! UndecidableInstances
并不是那么可怕;所有这一切意味着编译器可以代替查找实例,进入无限循环。这个听起来很糟糕,直到你意识到GHC实际上对找到一个实例需要的步骤数量有限制;除非你写了一个不好的实例,否则什么都不会发生错误,并且你得到的错误信息通常会非常明显地出现问题。 1 当然,它比 OverlappingInstances
(或者更糟糕的是, IncoherentInstances
)。
MonadError
具有从 m
到 e
的函数依赖关系。这意味着 m
的选择决定了 e
必须是什么;即每个 m
仅与一个 e
相关联。对这个(Coverage Condition)的检查是保守的,所以很容易遇到这样的问题,在这里你试着和递减一个级别来指定 e
。
MonadError
if the transformed monad is an instance. Basically I want my transformer to behave as the built-in transformers do, for example there is a MonadError
instance for StateT
:MonadError e m => MonadError e (StateT s m)
instance MonadError e m => MonadError e (MyMonadT m)
UndecidableInstances
isn't all that scary; all it means is that the compiler could, instead of finding an instance, go into an infinite loop. That sounds pretty bad, until you realise that GHC actually has a limit to the number of steps it'll take to find an instance; nothing will go wrong unless you write a bad instance, and the error messages you get will generally make it very obvious what's gone wrong.1 Certainly it's a lot less scary than things like OverlappingInstances
(or worse, IncoherentInstances
).MonadError
has a functional dependency from m
to e
. That means that the choice of m
determines what e
must be; i.e. every m
is associated with only one e
. The check for this (the Coverage Condition) is conservative, so it's easy to run into problems like this, where you try and "recurse down a level" to specify e
.