Difference between revisions of "Monad Transformers"
(explanation of transformers set of packages) 
(FAQ) 

Line 6:  Line 6:  
** [http://hackage.haskell.org/package/transformers transformers]: Provide only concrete transformers like <hask>StateT</hask>. The monad <hask>State s a</hask> is only a type synonym for <hask>StateT s Identity a</hask>. Thus both <hask>State</hask> and <hask>StateT</hask> can be accessed by the same methods like <hask>put</hask> and <hask>get</hask>. However, this only works, if <hask>StateT</hask> is the topmost transformer in a monad transformer stack. This package is Haskell 98 and thus can be also used with [[JHC]]. 
** [http://hackage.haskell.org/package/transformers transformers]: Provide only concrete transformers like <hask>StateT</hask>. The monad <hask>State s a</hask> is only a type synonym for <hask>StateT s Identity a</hask>. Thus both <hask>State</hask> and <hask>StateT</hask> can be accessed by the same methods like <hask>put</hask> and <hask>get</hask>. However, this only works, if <hask>StateT</hask> is the topmost transformer in a monad transformer stack. This package is Haskell 98 and thus can be also used with [[JHC]]. 

** [http://hackage.haskell.org/package/monadsfd monadsfd]: Provides the same type classes with functional dependencies like MTL. They allow using <hask>State</hask> methods also for <hask>StateT</hask> transformers within a transformer stack. 
** [http://hackage.haskell.org/package/monadsfd monadsfd]: Provides the same type classes with functional dependencies like MTL. They allow using <hask>State</hask> methods also for <hask>StateT</hask> transformers within a transformer stack. 

−  ** [http://hackage.haskell.org/package/monadstf monadstf]: Provides a different abstraction using [[type families]]. Unfortunately the names of <code>monadsfd</code> and <code>monadstf</code> clash, 
+  ** [http://hackage.haskell.org/package/monadstf monadstf]: Provides a different abstraction using [[type families]]. Unfortunately the names of <code>monadsfd</code> and <code>monadstf</code> clash, thus you can currently not import both packages in one package. 
−  thus you can currently not import both packages in one package. 

−  
== How can I use MTL and transformers together? == 
== How can I use MTL and transformers together? == 

+  
+  Q: When I use ghc or ghci it complains about the same module names in mtl and transformers or monadsfd. How can I resolve these name clashes? 

+  A: You can use the <code>hidepackage</code> option of GHC. [[Cabal]] uses the <code>hideallpackages</code> option and then explicitly makes every package visible with <code>package</code>. 

== Shall I use MTL or transformers? == 
== Shall I use MTL or transformers? == 

+  
+  Transformers is Haskell 98 and thus more portable. 

== How to move from MTL to transformers? == 
== How to move from MTL to transformers? == 

−  +  Many package using <code>MTL</code> can be ported to <code>transformers</code> with only slight modifications. 

Modules require the <code>Trans</code> infix, 
Modules require the <code>Trans</code> infix, 

e.g. <hask>import Control.Monad.State ...</hask> must be replaced by <hask>import Control.Monad.Trans.State ...</hask>. 
e.g. <hask>import Control.Monad.State ...</hask> must be replaced by <hask>import Control.Monad.Trans.State ...</hask>. 

Since <hask>State</hask> is only a type synonym, there is no longer a constructor named <hask>State</hask>. 
Since <hask>State</hask> is only a type synonym, there is no longer a constructor named <hask>State</hask>. 

−  For constructing you must use the function <hask>state</hask> and instead of 
+  For constructing you must use the function <hask>state</hask> and instead of matching patterns you must call <hask>runState</hask>. 
== See also == 
== See also == 
Revision as of 23:14, 5 March 2010
There are currently two sets of packages that implement similar interfaces to monad transformers, besides a third package with a similar goal but different API named MonadLib:
 MTL  Monad Transformers Library: provides concrete monad transformers like
StateT
and abstractions using multiparameter type classes with functional dependencies likeMonadState
. Monads likeState
and their transformer counterparts likeStateT
are distinct types and can be accessed uniformly only through a type class abstraction likeMonadState
. Because of the functional dependencies, MTL can currently (201003) only used in Hugs and GHC. MTL was the first implementation.  The newer implementation is derived from the former one and is split into the following components:
 transformers: Provide only concrete transformers like
StateT
. The monadState s a
is only a type synonym forStateT s Identity a
. Thus bothState
andStateT
can be accessed by the same methods likeput
andget
. However, this only works, ifStateT
is the topmost transformer in a monad transformer stack. This package is Haskell 98 and thus can be also used with JHC.  monadsfd: Provides the same type classes with functional dependencies like MTL. They allow using
State
methods also forStateT
transformers within a transformer stack.  monadstf: Provides a different abstraction using type families. Unfortunately the names of
monadsfd
andmonadstf
clash, thus you can currently not import both packages in one package.
 transformers: Provide only concrete transformers like
Contents
How can I use MTL and transformers together?
Q: When I use ghc or ghci it complains about the same module names in mtl and transformers or monadsfd. How can I resolve these name clashes?
A: You can use the hidepackage
option of GHC. Cabal uses the hideallpackages
option and then explicitly makes every package visible with package
.
Shall I use MTL or transformers?
Transformers is Haskell 98 and thus more portable.
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
 Monad Transformers Explained
 http://www.haskell.org/pipermail/libraries/2009March/011415.html
 http://www.haskell.org/pipermail/libraries/2009December/012914.html
 http://www.haskell.org/pipermail/haskellcafe/2010January/071842.html
 http://www.mailarchive.com/debianhaskell@lists.debian.org/msg01241.html