Monad Transformers

From HaskellWiki
Jump to navigation Jump to search

There are currently several packages that implement similar interfaces to monad transformers (besides an additional package with a similar goal but different API named MonadLib):

  • transformers: provides the classes MonadTrans and MonadIO, as well as concrete monad transformers such as StateT. The monad State s a is only a type synonym for StateT s Identity a. Thus both State and StateT can be accessed by the same methods like put and get. However, this only works if StateT is the top-most transformer in a monad transformer stack. This package is Haskell 98 and thus can be also used with JHC.
  • mtl (Monad Transformer Library) comes in two versions:
    • version 1 was the first implementation, containing the classes MonadTrans and MonadIO, concrete monad transformers such as StateT and multi-parameter type classes with functional dependencies such as MonadState. Monads like State and their transformer counterparts like StateT are distinct types and can be accessed uniformly only through a type class abstraction like MonadState. This version is now obsolete.
    • version 2 re-exports the classes and monad transformers of the transformers package, and adds multi-parameter type classes with functional dependencies such as MonadState.
    Version 2 of the MTL has some small incompatibilities relative to version 1. See "Upgrading from MTL 1 to MTL 2" for instructions on how to make code written for version 1 work with version 2.
Because of the functional dependencies, MTL can currently (2010-03) only used in Hugs and GHC. MTL was the first implementation.
  • monads-fd: this was the prototype of the new mtl implementation. It is now obsolete, and simply re-exports mtl version 2.
  • monads-tf: Provides a different abstraction using type families. Unfortunately the module names of mtl and monads-tf clash, so you can currently not import both packages in one package.

How can I use MTL and transformers together?

MTL and transformers use different module names, but share common classes, type constructors and functions, so they are fully compatible.

Shall I use MTL or transformers?

Transformers is Haskell 98 and thus more portable, and doesn't tie you to functional dependencies. But because it lacks the monad classes, you'll have to lift operations to the composite monad yourself (examples).

How to move from MTL to transformers?

Many package using MTL can be ported to transformers with only slight modifications. Modules require the Trans infix, e.g. import Control.Monad.State ... must be replaced by import Control.Monad.Trans.State .... Since State is only a type synonym, there is no longer a constructor named State. For constructing you must use the function state and instead of matching patterns you must call runState.

See also