blame: mtl MonadReader instance for ContT
schlepptop at henning-thielemann.de
Tue Dec 23 16:37:07 EST 2008
Nicolas Frisby schrieb:
> This mtl instance is in conflict with a usage of shift/reset that I'm
> porting from ML (Sheard's type-directed partial evaluator).
>> instance (MonadReader r' m) => MonadReader r' (ContT r m) where
>> local f m = ContT $ \c -> do
>> r <- ask
>> local f (runContT m (local (const r) . c))
> I need to remove the "local (const r)" bit. I think this is just a
> different point in the diverse design space of dynamic
> binding/delimited control. Since Haskell lacks visibility management
> for importing instances, I'm forced to duplicate the rest of the ContT
> code in order to replace this instance with my own.
You may define a newtype, lift all required instances with
-XGeneralizedNewtypeDeriving and define your own MonadReader instance.
> 1) I am hoping this list can recall the reason for putting this design
> decision into the mtl. Perhaps there's a reason to prefer this
> particular side-effect interaction.
> 2) I am suggesting that the mtl be restructured such that this
> instance be delegated to a separate module so that
> i) I can avoid importing it along with the other useful instances
> ii) and the mtl could provide alternative instances.
> An alternative to breaking out the modules would be to not provide
> the instance.
> Another, more radical alternative could involve phantom types.
> I don't know of any in the mtl, but this same consideration might be
> applicable to other libraries with "arbitrary" instances.
It was discussed in length, that different instances for the same
class/type pair leads to trouble sooner or later. (keyword "orphan
instances") - Just imagine people who import two instances via two
different import paths, then the compiler does not know, which instances
Instead newtype is the answer.
More information about the Libraries