A bunch of them are almost completely equivalent:
mtluses GHC extensions, buttransformersis Haskell 98.monads-fdandmonads-tfare add-ons totransformers, using functional dependencies and type families respectively, both providing the functionality inmtlthat’s missing fromtransformers.mtl-tfismtlreimplemented using type families.
So essentially, mtl == transformers ++ monads-fd, mtl-tf == transformers ++ monads-tf. The improved portability and modularity of transformers and its associated packages is why mtl is uncool these days, I think.
mmtl and mtlx both seem to be similar to and/or based on mtl, with API differences and extra features.
MonadLib seems to have a rather different take on matters, but I’m not familiar with it directly. Also seems to use a lot of GHC extensions, more than the others.
At a glance compose-trans seems to be more like metaprogramming stuff for creating monad transformers. It claims to be compatible with Control.Monad.Trans which… I guess means mtl?
At any rate, I’d suggest the following decision algorithm:
- Do you need standard monads for a new project? Use
transformers& co., help us laymtlto rest. - Are you already using
mtlin a large project?transformersisn’t completely compatible, but no one will kill you for not switching. - Does one of the other packages provide unusual functionality that you need? Might as well use it rather than rolling your own.
- Still unsatisfied? Throw them all out, download
category-extras, and solve all the world’s problems with a page and a half ofincomprehensible abstract nonsensebreathtakingly generic code.