You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Imagine that I have a monad-transformer transformer; that is, a datatype which is parameterized on a monad transformer, and which is itself a monad transformer. This came up for me in the context of writing a wrapper layer that applied additional semantics around an existing monad transformer under my control.
Then, it is impossible to ever write a MonadTransControl instance on this datatype. (It's also impossible to write MonadTrans).
The reason is quite simple: The types of the liftWith and restoreT methods each introduce an additional constraint on Monad m, for an arbitrary monad not mentioned in the class signature. To write my wrapper, I need to invoke these methods recursively, calling them on the inner layer, as in:
But these inner methods are looking for an instance Monad (innerT m), for all m. This condition in fact holds, since innerT is itself a monad transformer, but there is no way to ever prove it to Haskell!
It cannot be deduced from the existence of a relevant instance elsewhere, because that is not how instance constraints work; rather, only instances explicitly mentioned in some context are relevant to what the compiler is trying to prove. The relevant contexts are those on the method definitions, the instance definition, and the class definition. Since m is introduced at the method level, it is out-of-scope and cannot be mentioned at the instance level.
So, this true fact can neither be deduced automatically, nor supplied explicitly. How Gödelian.
I'm filing this bug here, and I will also file it against the base package if it turns out to be easy to do so, since, as I noted MonadTrans has the same problem. I don't have a solution in mind, and I don't expect that anyone else does either, but I want the issue to be well-described so that future architects can chew on it. I will not be hurt when this inevitably gets closed as WONTFIX! :)
By the way - to anyone finding this via google - my sympathies! What I ultimately did was implement MonadBase and MonadBaseControl directly, rather than using the default* helpers, which introduce otherwise-unneeded constraints on MonadTrans and MonadTransControl.
The text was updated successfully, but these errors were encountered:
I don't own that code and no longer have a copy of it, sorry. What I ultimately did was to use monad-control only for the layers below this one in the stack, modifying all call sites to manually lift past it, as if by inlining the hypothetical MonadTransControl instance.
Imagine that I have a monad-transformer transformer; that is, a datatype which is parameterized on a monad transformer, and which is itself a monad transformer. This came up for me in the context of writing a wrapper layer that applied additional semantics around an existing monad transformer under my control.
Then, it is impossible to ever write a
MonadTransControl
instance on this datatype. (It's also impossible to writeMonadTrans
).The reason is quite simple: The types of the
liftWith
andrestoreT
methods each introduce an additional constraint onMonad m
, for an arbitrary monad not mentioned in the class signature. To write my wrapper, I need to invoke these methods recursively, calling them on the inner layer, as in:But these inner methods are looking for an instance
Monad (innerT m)
, for allm
. This condition in fact holds, sinceinnerT
is itself a monad transformer, but there is no way to ever prove it to Haskell!It cannot be deduced from the existence of a relevant instance elsewhere, because that is not how instance constraints work; rather, only instances explicitly mentioned in some context are relevant to what the compiler is trying to prove. The relevant contexts are those on the method definitions, the instance definition, and the class definition. Since
m
is introduced at the method level, it is out-of-scope and cannot be mentioned at the instance level.So, this true fact can neither be deduced automatically, nor supplied explicitly. How Gödelian.
I'm filing this bug here, and I will also file it against the base package if it turns out to be easy to do so, since, as I noted
MonadTrans
has the same problem. I don't have a solution in mind, and I don't expect that anyone else does either, but I want the issue to be well-described so that future architects can chew on it. I will not be hurt when this inevitably gets closed as WONTFIX! :)By the way - to anyone finding this via google - my sympathies! What I ultimately did was implement
MonadBase
andMonadBaseControl
directly, rather than using thedefault*
helpers, which introduce otherwise-unneeded constraints onMonadTrans
andMonadTransControl
.The text was updated successfully, but these errors were encountered: