[Haskell-cafe] upgrading mtl1 to mtl2

Evan Laforge qdunkan at gmail.com
Thu Feb 17 08:52:12 CET 2011


On Wed, Feb 16, 2011 at 11:28 PM, Sebastian Fischer <fischer at nii.ac.jp> wrote:
> On Thu, Feb 17, 2011 at 11:32 AM, Evan Laforge <qdunkan at gmail.com> wrote:
>>
>> Or will there just be massive signature rewriting in the wake of mtl2?
>
> I must admit I still don't understand your exact problem. Could you help me
> with an example where using mtl2 requires an additional (Functor m)
> constraint that is not required when using mtl1?

Sure.  It could be I'm doing it wrong too, since I'm far from sure of
myself here, and that's why I posted in the first place.  Say you have
a widely used monad:

type CmdStack m = ThisT (ThatT m)

newtype CmdT m a = CmdT (CmdStack m a)
    deriving (Everything)
run_cmd_t (CmdT x) = x

abort :: (Monad m) => CmdT m a
abort = Error.throwError State.Abort

f1 :: (Monad m) => CmdT m X
f1 = fmap ...

... Follows are many modules full of functions that look like 'f1', or
transitively call 'f1'.  It used to be that (Monad m) implied (Functor
m) but now evidently that is no longer so (the error is 'Could not
deduce (Functor m) from the context (Monad m)').  The result is that
every function that touches an fmap-using function needs a (Functor m)
constraint.  It goes for Applicative too, but evidently Applicative
has Functor as a superclass, so adding just one is enough.

It's even more fun because many functions may not require (Functor
m)... but if you add an 'fmap' or <$> to something other functions
call, I'm guessing there will be a ripple effect where you have to add
Functor to every function that transitively calls it.  So now when
writing new functions you can choose between the wordy safe way or the
concise way which might work now but break later.

I don't really understand what benefit I get from the change, but
hopefully it's significant because the signatures do get significantly
uglier and it affects every single one.  And since there's no way to
abstract over class contexts aside from declaring a dummy class,
there's no way that I know of to insulate from changes like this.



More information about the Haskell-Cafe mailing list