Home > Uncategorized > Removing mtl dependency

Removing mtl dependency

In Haskell, there are a variety of monad transformer libraries. The most popular is the original library, mtl, which is in the Haskell platform. Many people mutter complaints about mtl, including poor design, use of functional dependencies (which are somewhat out of favour these days) and inefficient implementation. Several replacements have been developed — direct replacements such as the transformers and mmtl libraries, and also packages like monadLib.

This issue arose again recently in a reddit discussion, with people wondering when mtl is going to be replaced. CHP used to make a lot of (internal) use of monad transformers from the mtl package. I’ve recently refactored the CHP monad, which removed a large part of that dependency: gone are ErrorT and ReaderT, in comes a continuation-passing style. If I want to, I’m now able to make the next version of CHP not depend on mtl (nor on any other monad transformer library). I’m not sure if this is worth doing — does it actually make anyone’s life easier using CHP if it doesn’t depend on mtl?

The only external change that would result from giving up mtl in the chp package is the MonadIO CHP instance. MonadIO is a useful type-class in mtl for any monad (like CHP) that sits on top of IO. I would stop having an instance of MonadIO CHP in the CHP library, and would instead provide a liftIO_CHP :: IO a -> CHP a function for the same purpose, which could then be used in a MonadIO instance for CHP in your own package (using MonadIO from mtl, or from transformers, or whatever your favourite monad transformer library is). There was a recent proposal to split MonadIO from mtl because it’s so useful (and can be stand-alone) but that hasn’t happened yet. The change from liftIO to the function liftIO_CHP would actually be slightly beneficial for me (due to some other work going on) but could be a pain to users who don’t care about mtl/transformers and who don’t want to have to alter their existing code.

If you are bothered either way — keeping mtl and the MonadIO instance in CHP versus removing them — speak up.

Categories: Uncategorized
  1. April 9, 2010 at 12:44 pm

    I would keep MonadIO instance in CHP. However with package imports you can have best of both worlds:

    
    import Control.Monad.IO.Class as Trans
    import Control.Monad.Trans from "mtl" as MTL
    
    instance MTL.MonadIO CHP where
        ...
    
    instance Trans.MonadIO CHP where
       ...
    

    The drawback is that the CHP would depend on both mtl and transformers.

    • Ivan Miljenovic
      April 9, 2010 at 11:56 pm

      I was under the impression that package imports was an evil hidden extension that is there only because GHC needs it, and that package developers shouldn’t be using it.

  2. April 9, 2010 at 2:13 pm

    I’m still pretty early in my “CHP-based web framework” work, but of the two libraries I tried to combine CHP with, both of them have caused me conflicts due to them using transformers and CHP using mtl.

    If CHP switches then I can get a pure Haskell stack from webserver on; right now I’m having to use FastCGI.

  3. Saizan
    April 9, 2010 at 4:22 pm

    if you switch, use something better than transformers, it keeps all the really broken things that are in mtl.

  4. April 9, 2010 at 5:06 pm

    I support removing the dependency.

  5. April 9, 2010 at 5:31 pm

    Is there any value in separating the instancing off into other libs like chp-mtl, chp-transformers, chp-mmtl? These would depend on the general chp library where the existing code lives without the trans instances.

    So if I wanted to use chp with mtl, I would install and import things from chp and chp-mtl

    • April 9, 2010 at 7:45 pm

      I did wonder about having chp-mtl, etc. The main drawbacks are the libraries will only contain a couple of orphan instances (so barely worth having), and a proliferation of chp-* libraries might be a bit off-putting to new users. Worth thinking about, though.

  6. April 10, 2010 at 1:21 am

    If you force everyone to define their own MonadIO instance for CHP, then any two libraries that define their own such instance cannot be used together. There has to be a better way.

    • April 10, 2010 at 7:48 am

      That’s a good point — and seems to indicate that I should adopt Dino Morelli’s suggestion.

  7. Syzygies
    April 10, 2010 at 2:00 pm

    Re: “functional dependencies (which are somewhat out of favour these days)”

    After a stint away from Haskell, programming in the tiny language Scheme, I don’t go looking for trouble while programming in Haskell. One learns through bloody experience why many of the GHC extensions exist: There are holes in the standard language, like a toolbox missing a screwdriver. One hits the same obstacle so many times that its shape becomes clear even to a novice, and the “fix” in GHC then jumps out at you, standing apart from many extensions one hopes to never need to understand. Functional dependencies are such an extension.

    So what’s a good reference to a tutorial teaching people how to solve problems in practice that appear to require functional dependencies, without using them? It would be good form to have given such a reference, to support the dig at functional dependencies. I’m not defending them, but it’s hard to single them out for scorn when Haskell as a whole is so much more ornately complex than Scheme. Haskell is nevertheless a better language, and one lives with what one needs to do.

  8. May 3, 2010 at 5:36 pm

    Thanks for all the comments. It took slightly longer than planned, but I’ve now released CHP-2.2.0 with the mtl dependency removed. If you want instances involving CHP for any monad transformer libraries besides mtl and transformers, just let me know and I’ll happily create, upload and maintain packages for them.

  1. April 22, 2010 at 11:31 am
  2. May 3, 2010 at 5:22 pm

Leave a reply to Ivan Miljenovic Cancel reply