Making a custom monad transformer an instance of MonadError

对着背影说爱祢 提交于 2019-12-07 05:29:50

问题


I want to make my monad transformer to be an instance of 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)

I tried doing this:

instance MonadError e m => MonadError e (MyMonadT m)

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?


回答1:


This is basically fine. 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).

The reason it complains is because 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.

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.



来源:https://stackoverflow.com/questions/9951382/making-a-custom-monad-transformer-an-instance-of-monaderror

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!