mtl: Context of execWriterT

Hi, I have a question about the context of the execWriterT function, in Control.Monad.Writer of the mtl package. The current context forces the containter type to be a Monad, while is enough a Functor. Yes, WriterT is a monad transformer, so this is not a problem, but I have as a law to write the less restrictive context for every function. So, is there any reason to do this context more restrictive? If not, the obvious way to do it may be: execWriterT :: Functor m => WriterT w m a -> m w execWriterT = fmap snd . runWriterT However, I thought that there must be a reason explaining this fact.

On Thursday 14 April 2011 14:25:39, Daniel Díaz wrote:
Hi,
I have a question about the context of the execWriterT function, in Control.Monad.Writer of the mtl package. The current context forces the containter type to be a Monad, while is enough a Functor. Yes, WriterT is a monad transformer, so this is not a problem, but I have as a law to write the less restrictive context for every function.
So, is there any reason to do this context more restrictive?
Alas, Functor is not a superclass of Monad, so a Monad constraint is not more restrictive than a Functor constraint. And e.g. in mtl-2.*, we have instance Functor m => Functor (Control.Monad.Trans.State.Lazy.StateT s m) which used to have a Monad constraint (same for WriterT), a change that broke some code (previously, one could have foo :: (Monad m) => ... StateT s m a ... foo -- uses the Functor instance , now you have to have foo :: (Monad m, Functor m) => ... StateT s m a ... if you use both, Functor and Monad, in foo).
If not, the obvious way to do it may be:
execWriterT :: Functor m => WriterT w m a -> m w execWriterT = fmap snd . runWriterT
However, I thought that there must be a reason explaining this fact.

On Thu, Apr 14, 2011 at 03:02:18PM +0200, Daniel Fischer wrote:
Alas, Functor is not a superclass of Monad, so a Monad constraint is not more restrictive than a Functor constraint.
Yes, that is the issue -- as those classes are now, making this change would break programs. Several functions are affected by the same issue: ReaderT: ask asks StateT: evalStateT execStateT get put gets liftListen liftPass WriterT: execWriterT tell listen listens pass censor It's particularly annoying for ReaderT and WriterT, now that they're Applicative transformers as well as Monad transformers.
participants (3)
-
Daniel Díaz
-
Daniel Fischer
-
Ross Paterson