diff --git a/Math/MFSolve.hs b/Math/MFSolve.hs
--- a/Math/MFSolve.hs
+++ b/Math/MFSolve.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE DeriveGeneric, PatternGuards, PatternSynonyms, MultiParamTypeClasses, FlexibleContexts, DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric, PatternGuards, PatternSynonyms, MultiParamTypeClasses, FlexibleContexts, DeriveDataTypeable, GeneralizedNewtypeDeriving #-}
 
 {-|
 Module      : Math.MFSolve
@@ -23,7 +23,8 @@
 === Examples:
 
 Let's define some variables.  The `SimpleVar` type is a simple wrapper
-around `String` to provide nice output.
+around `String` to provide nice output, since the Show instance for
+`String` outputs quotation marks.
 
 > let [x, y, t, a] = map (makeVariable . SimpleVar) ["x", "y", "t", "a"]
 
@@ -76,26 +77,35 @@
 -}
 
 module Math.MFSolve
-       (-- * Types
-        MFSolver, SimpleExpr(..), Expr, LinExpr(..), UnaryOp(..), BinaryOp(..),
-        Dependencies, DepError(..), SimpleVar(..),
-        -- * Expressions
-        evalSimple, evalExpr, fromSimple, toSimple, makeVariable,
-        makeConstant, hasVar, 
+       (-- * Expressions
+        SimpleExpr(..), Expr, LinExpr(..), UnaryOp(..), BinaryOp(..),
+        SimpleVar(..),
+        makeVariable,
+        makeConstant, evalExpr, fromSimple, toSimple, evalSimple, hasVar, 
         -- * Dependencies
+        Dependencies, DepError(..), 
+        noDeps, addEquation, eliminate,
         getKnown, knownVars, varDefined, nonlinearEqs, dependendVars,
-        noDeps, 
-        eliminate, addEquation,
         -- * Monadic Interface
-        dependencies, getValue, getKnownM, varDefinedM, eliminateM,
-        (=&=), (===), ignore,  
-        runSolver, evalSolver, execSolver, unsafeSolve, showVars)
+        (===), (=&=), dependencies, getValue, getKnownM,
+        varDefinedM, eliminateM, ignore,
+        -- * MFSolver monad
+        MFSolver, 
+        runSolver, evalSolver, execSolver, unsafeSolve, showVars,
+        -- * MFSolverT monad transformer
+        MFSolverT, 
+        runSolverT, evalSolverT, execSolverT, unsafeSolveT)
 where
 import qualified Data.HashMap.Strict as M
 import qualified Data.HashSet as H
 import GHC.Generics
 import Control.Monad.Except
 import Control.Monad.State
+import Control.Monad.Reader
+import Control.Monad.Writer
+import Control.Monad.Identity
+import Control.Monad.RWS
+import Control.Monad.Cont
 import Control.Exception
 import Data.Typeable
 import Control.Applicative hiding (Const)
@@ -112,7 +122,8 @@
   Tan | Sinh | Asin | Acos | Asinh | Acosh | Atan
   deriving (Eq, Generic)
 
--- | A simplified datatype representing an expression
+-- | A simplified datatype representing an expression.  This can be
+-- used to inspect the structure of a `Expr`, which is hidden.
 data SimpleExpr v n =
   SEBin BinaryOp (SimpleExpr v n) (SimpleExpr v n) |
   SEUn UnaryOp (SimpleExpr v n) |
@@ -122,7 +133,9 @@
 newtype SimpleVar = SimpleVar String
                   deriving (Eq, Ord, Generic)
 
--- | An mathematical expression of several variables.
+-- | A mathematical expression of several variables. Several Numeric
+-- instances (`Num`, `Floating` and `Fractional`) are provided, so
+-- doing calculations over `Expr` is more convenient.
 data Expr v n = Expr (LinExpr v n) [TrigTerm v n] [NonLinExpr v n]
                 deriving (Generic)
 
@@ -170,13 +183,20 @@
 instance Show SimpleVar where
   show (SimpleVar s) = s
 
--- | An opaque datatype containing the dependencies of each variable.
--- A variable who's dependency is just a number is called /known/.  A
--- variables which depends on other variables is called /dependend/.
--- A variable which is neither known or dependend is called
--- /independend/.  A variable can only depend on other /independend/
--- variables.  It also contains nonlinear equations which it couldn't
--- reduce to a linear equation yet.
+-- | This hidden datatype represents a system of equations.  It
+-- contains linear dependencies on variables as well as nonlinear
+-- equations. The following terminology is used from /metafont/:
+-- 
+--   * /known variable/: A variable who's dependency is just a number.
+--   
+--   * /dependend variable/: A variable which depends linearly on other variables.
+--
+--   * /independend variable/: any other variable.
+--
+-- A /dependend/ variable can only depend on other /independend/
+-- variables.  Nonlinear equations will be simplified by substituting
+-- and evaluating known variables, or by reducing some trigonometric
+-- equations to linear equations.
 data Dependencies v n = Dependencies
                         (M.HashMap v (H.HashSet v))
                         (LinearMap v n)
@@ -184,18 +204,18 @@
                         (TrigEq2 v n)
                         [Expr v n]
                         
--- | An error type for '===', '=&=' and 'solveEq':
+-- | An error type for '===', '=&=' and 'addEquation':
 data DepError v n =
-  -- | 'UndefinedVar' @v@: The variable is not defined.
+  -- | The variable is not defined.
   UndefinedVar v |
-  -- | 'UnknownVar' @v@: The variable is defined but dependend an other variables.
+  -- | The variable is defined but dependend an other variables.
   UnknownVar v n |
-  -- | 'InconsistentEq' @a@: The equation was reduced to the
+  -- | The equation was reduced to the
   -- impossible equation `a == 0` for nonzero a, which means the
   -- equation is inconsistent with previous equations.
   InconsistentEq n |
-  -- | 'RedundantEq': The equation was reduced to the redundant equation 0 == 0, which
-  -- means it doesn't add any information.
+  -- | The equation was reduced to the redundant equation `0 == 0`,
+  -- which means it doesn't add any information.
   RedundantEq
   deriving Typeable
 
@@ -204,37 +224,20 @@
 instance (Ord n, Num n, Eq n, Show v, Show n) => Show (Expr v n) where
   show e = show (toSimple e)
 
--- | A monad for solving equations.  Basicly just a state and exception monad.
-newtype MFSolver v n a = MFSolver {
-  -- | Unwrap a solver monad as a function.
-  runSolver :: Dependencies v n -> Either (DepError v n) (Dependencies v n, a) }
-
-instance Monad (MFSolver v n) where
-  MFSolver s >>= f = MFSolver $ \dep ->
-    case s dep of
-     Left err -> Left err
-     Right (dep2, val) ->
-       runSolver (f val) dep2
-  return a = MFSolver $ \dep -> Right (dep, a)
+-- | A monad transformer for solving equations.  Basicly just a state and exception monad transformer over `Dependencies` and `DepError`.
+newtype MFSolverT v n m a = MFSolverT (StateT (Dependencies v n) (ExceptT (DepError v n) m) a)
+                            deriving (Functor, Applicative, Monad, MonadIO, MonadState (Dependencies v n),
+                                      MonadError (DepError v n), MonadReader s, MonadWriter s,
+                                      MonadCont)
 
-instance (MonadState (Dependencies v n)) (MFSolver v n) where
-  get = MFSolver $ \dep -> Right (dep, dep)
-  put dep = MFSolver $ const $ Right (dep, ())
-           
-instance (MonadError (DepError v n)) (MFSolver v n) where
-  throwError e = MFSolver $ const $ Left e
-  catchError s h = MFSolver $ \dep ->
-    case runSolver s dep of
-     Left e -> runSolver (h e) dep
-     v -> v
+instance MonadTrans (MFSolverT v n) where
+  lift = MFSolverT . lift. lift
 
-instance Functor (MFSolver v n) where
-  fmap f s = MFSolver $ \dep ->
-    fmap f <$> runSolver s dep 
+runSolverT :: MFSolverT v n m a -> Dependencies v n -> m (Either (DepError v n) (a, Dependencies v n))
+runSolverT (MFSolverT s) = runExceptT . runStateT s 
 
-instance Applicative (MFSolver v n) where
-  (<*>) = ap
-  pure = return
+-- | A monad for solving equations.  Basicly just a state and exception monad over `Dependencies` and `DepError`.
+type MFSolver v n a = MFSolverT v n Identity a
 
 withParens :: (Show t1, Show t, Ord t1, Num t1, Eq t1) => SimpleExpr t t1 -> [BinaryOp] -> String
 withParens e@(SEBin op _ _) ops
@@ -596,7 +599,7 @@
   foldr ((+).substVarTrig s) 0 trig +
   foldr ((+).substVarNonLin s) 0 nl
 
--- | An empty set of dependencies.
+-- | An empty system of equations.
 noDeps :: Dependencies v n
 noDeps = Dependencies M.empty M.empty [] M.empty []
 
@@ -618,7 +621,7 @@
 addEqs :: (Hashable v, Hashable n, RealFrac (Phase n), Ord v, Floating n) => Dependencies v n -> [Expr v n] -> Either (DepError v n) (Dependencies v n)
 addEqs = foldM addEquation
 
--- | @addEquation e d@: Add the equation @e = 0@ to the system d.
+-- | @addEquation d e@: Add the equation @e = 0@ to the system d.
 addEquation :: (Hashable n, Hashable v, RealFrac (Phase n), Ord v,
           Floating n) =>
          Dependencies v n
@@ -796,6 +799,9 @@
 -- | Eliminate an variable from the equations.  Returns the eliminated
 -- equations.  Before elimination it performs substitution to minimize
 -- the number of eliminated equations.
+-- 
+--__Important__: this function is
+-- still experimental and mostly untested.
 eliminate :: (Hashable n, Show n, Hashable v, RealFrac (Phase n), Ord v, Show v,
               Floating n) => Dependencies v n -> v -> (Dependencies v n, [Expr v n])
 eliminate (Dependencies vdep lin trig trig2 nonlin) v
@@ -1028,18 +1034,46 @@
   \e -> case e of
          RedundantEq -> return ()
          _ -> throwError e)
-  
+
+-- | run the solver.
+runSolver :: MFSolver v n a -> Dependencies v n -> Either (DepError v n) (a, Dependencies v n)
+runSolver s = runIdentity . runSolverT s
+           
+-- | Return the result of solving the equations, or throw the error as an exception.  Monadic version.
+unsafeSolveT :: (Show n, Show v, Typeable n, Typeable v, Monad m) =>
+                Dependencies v n -> MFSolverT v n m a -> m a
+unsafeSolveT dep s = do
+  res <- runSolverT s dep
+  case res of
+   Right (v, _) -> return v
+   Left e -> throw e
+
+-- | Return the result of solving the equations or an error.  Monadic version.
+evalSolverT :: Functor f =>
+               MFSolverT v n f b
+            -> Dependencies v n -> f (Either (DepError v n) b)
+evalSolverT s dep =
+  fmap fst <$> runSolverT s dep 
+
+-- | Run the solver and return the dependencies or an error.  Monadic version.
+execSolverT :: Functor m =>
+               MFSolverT v n m a
+            -> Dependencies v n -> m (Either (DepError v n) (Dependencies v n))
+execSolverT s dep =
+  fmap snd <$> runSolverT s dep
+
 -- | Return the result of solving the equations, or throw the error as an exception.
-unsafeSolve :: (Typeable n, Typeable v, Show n, Show v) => MFSolver v n a -> Dependencies v n -> a
-unsafeSolve s dep = case runSolver s dep of
-  Right (_, v) -> v
-  Left e -> throw e
+unsafeSolve :: (Typeable n, Typeable v, Show n, Show v) =>
+               Dependencies v n -> MFSolver v n a -> a
+unsafeSolve dep = runIdentity . unsafeSolveT dep
 
 -- | Return the result of solving the equations or an error.
-evalSolver :: MFSolver v n a -> Dependencies v n -> Either (DepError v n) a
-evalSolver s dep = snd <$> runSolver s dep 
+evalSolver :: MFSolver v n a
+           -> Dependencies v n -> Either (DepError v n) a
+evalSolver s = runIdentity . evalSolverT s
 
 -- | Run the solver and return the dependencies or an error.
-execSolver :: MFSolver v n a -> Dependencies v n -> 
-              Either (DepError v n) (Dependencies v n)
-execSolver s dep = fst <$> runSolver s dep
+execSolver :: MFSolver v n a
+           -> Dependencies v n -> Either (DepError v n) (Dependencies v n)
+execSolver s = runIdentity . execSolverT s
+
diff --git a/mfsolve.cabal b/mfsolve.cabal
--- a/mfsolve.cabal
+++ b/mfsolve.cabal
@@ -1,5 +1,5 @@
 Name:		mfsolve
-Version: 	0.2.0
+Version: 	0.3.0
 Synopsis:	Equation solver and calculator à la metafont
 Category: 	Math
 Copyright: 	Kristof Bastiaensen (2015)
