A lot of code could quite reasonably work with an mtl constraint that spans both versions if mtl-2 was the fundep version as long as it doesn't provide instances for the base monads, otherwise the dependency section of their cabal file would get complicated, having to switch packages at the 2.0 mark.
That way existing code would continue to work across the version bump if it didn't care about the type synonym issue for State, Reader, etc.
The question then becomes how to shuffle things around namespace wise?
As a straw man proposal to get things started:
transformers:
Control.Monad.Foo.Transformer - for the actual data type for FooT
mtl 2:
Control.Monad.Foo.Class - exports just the fundep-based typeclass and no instances, like now.
Control.Monad.Foo - exports the instances for the fundep based version and re-exports the Transformer and Class module contents.
Then the type-family package can provide:
mtl-tf:
Control.Monad.Foo.Family.Class - exports just the type-family based typeclass
Control.Monad.Foo.Family - exports the instances of the typefamily base version and re-exports the Transformer and Family.Class modules
This will safely let most libraries just use a constraint on mtl >= 1.2 && <= 2.1 in which case their code works across both versions, and if someone wants to use mtl-tf for clarity in their code, it will introduce no complications regardless of what libraries they import as long as those libraries can support both versions.
The final issue is whether or not it is a good idea to eliminate the simpler non-transformer versions of the monads.
Without them, libraries that provide instances for the various monads cannot provide instances for State and StateT in a way that lets them work compatibly with both versions.
So, an issue that I would like to talk about separately is if we _should_ be dropping the basic State, Reader, Writer, etc. constructors. They have definite pedagogical value, and have easier to understand behavior for introductory purposes. If we kept those then ALL code that worked with mtl 1.2 would be compatible with mtl 2, which strikes me as a desirable property. This has the benefit that it is easier to write libraries that export instances. I think we would be remiss in not at least considering the issue. On the other hand, I don't know how many libraries provide instances for the monads in the MTL. I have a few in my monoids library, but I'd be willing to go either way.
-Edward Kmett
On Sun, Nov 29, 2009 at 2:48 PM, Duncan Coutts
<duncan.coutts@googlemail.com> wrote:
On Sun, 2009-11-29 at 21:08 +0200, Michael Snoyman wrote:
>> Ok, how about this:
>>
>> transformers H98 bits, registered hidden by default
>> mtl 2 re-exports transformers, adds type function stuff
>> mtl-fd alternative that uses FDs, hidden by default
>>
> Are you saying that mtl-2 would be the equivalent of transformers +
> monads-tf? That might not be a good call; monads-fd is probably more
> popular than monads-tf.
Yes mtl-2 would be transformers + monads-${the-right-one}
Though more precisely, it'd re-export transformers and contain
monads-${the-right-one}.
I'm not really saying whether it should be the tf or fd version. I've
not been taking part in that discussion.
But other people have been discussing it and whichever one it is that
they agree is the right default, that one should be labelled as mtl
version 2.
Also, I should say that it would be wrong to push the choice of FDs/TFs
onto everyone. We should just pick one. Some people know the difference
and can select an alternative. Everyone else just wants to use the same
one as everyone else is using.