diff --git a/multistate.cabal b/multistate.cabal
--- a/multistate.cabal
+++ b/multistate.cabal
@@ -1,5 +1,5 @@
 Name:          multistate
-Version:       0.1.1
+Version:       0.1.2
 Cabal-Version: >= 1.8
 Build-Type:    Simple
 license:       BSD3
@@ -15,17 +15,46 @@
 
 Synopsis: like mtl's ReaderT/StateT, but more than one contained value/type.
 Description:
+  .
+  == Introduction
+  .
   When using multiple ReaderT's or StateT's in the same monad stack, it becomes
   necessary to lift the operations in order to affect a specific transformer.
   Using heterogenous lists (type level functions), a GADT and a corresponding
   type class, this package provides transformers that remove that necessity:
   MultiReaderT/MultiStateT can contain a heterogenous list of values.
+  .
   The type inferred for the getter/setter determines which value is
   read/written.
-  See the Example application for some very basic usage.
+  .
+  == Example
+  .
+  >              -- an IO action wrapped by a MultiState
+  >              -- containing both a Char and a [Char].
+  > examplePrint :: MultiStateT (Cons [Char] (Cons Char Null)) IO ()
+  > examplePrint = do
+  >   c  <- mGet             -- inferred to be :: m Char
+  >   cs <- mGet             -- inferred to be :: m [Char]
+  >   lift $ putStrLn (c:cs)
+  .
+  This computation can be executed in the following way:
+  .
+  > main = evalMultiStateT
+  >      $ withMultiState 'H'
+  >      $ withMultiState "ello, World!"
+  >      $ examplePrint
+  .
+  ( you can find this example as an executable in the package. )
+  .
+  == Known Deficits
+  .
   This package currently lacks a complete set of "lifting instances", i.e.
-  instance definitions for classes such as mtl's MonadReader "over" the newly
-  introduced monad transformers. These "lifting instances" would be necessary
+  instance definitions for classes such as mtl's MonadWriter "over" the newly
+  introduced monad transformers, as in
+  .
+  > instance (MonadWriter w m) => MonadWriter w (MultiStateT c m) where ..
+  .
+  These "lifting instances" would be necessary
   to achieve full compatability with existing transformers. Ping me if you
   find anything specific missing.
 
@@ -39,14 +68,14 @@
 
 flag build-example
   description: Build the MultiState-example example program
-  default: False  
+  default: False
 
 library {
   exposed-modules:
+    Data.HList.HList
     Control.Monad.MultiState
     Control.Monad.MultiReader
   other-modules:
-    Data.HList.HList
   build-depends:
     base >=4 && <6,
     mtl >=2 && <3,
diff --git a/src/Control/Monad/MultiReader.hs b/src/Control/Monad/MultiReader.hs
--- a/src/Control/Monad/MultiReader.hs
+++ b/src/Control/Monad/MultiReader.hs
@@ -4,17 +4,23 @@
 {-# LANGUAGE OverlappingInstances #-}
 {-# LANGUAGE UndecidableInstances #-}
 
+-- | The multi-valued version of mtl's Reader / ReaderT
+-- / MonadReader
 module Control.Monad.MultiReader
-  ( MultiReaderT(..)
+  ( -- * MultiReaderT
+    MultiReaderT(..)
   , MultiReaderTNull
   , MultiReader
+  -- * MonadMultiReader class
   , MonadMultiReader(..)
+  -- * functions
   , mAskRaw
   , withMultiReader
   , withMultiReaders
   , evalMultiReaderT
   , evalMultiReaderTWithInitial
   , mapMultiReaderT
+  -- * re-exports
   , Cons -- re-export that stuff to allow writing type signatures.
   , Null
 ) where
@@ -46,20 +52,48 @@
 
 
 
+-- | A Reader transformer monad patameterized by:
+--   
+-- * x - The list of types constituting the environment / input (to be read),
+-- * m - The inner monad.
+-- 
+-- 'MultiReaderT' corresponds to mtl's 'ReaderT', but can contain
+-- a heterogenous list of types.
+-- 
+-- This heterogenous list is represented using Types.Data.List, i.e:
+-- 
+--   * @'Null'@ - The empty list,
+--   * @'Cons' a b@ - A list where @/a/@ is an arbitrary type
+--     and @/b/@ is the rest list.
+-- 
+-- For example,
+-- 
+-- > MultiReaderT (Cons Int (Cons Bool Null)) :: (* -> *) -> (* -> *)
+-- 
+-- is a Reader wrapper containing the types [Int,Bool].
 newtype MultiReaderT x m a = MultiReaderT {
   runMultiReaderTRaw :: StateT (HList x) m a
 }
 
+-- | A MultiReader transformer carrying an empty state.
 type MultiReaderTNull = MultiReaderT Null
 
-type MultiReader x a = MultiReaderT x Identity a
+-- | A reader monad parameterized by the list of types x of the environment
+-- / input to carry.
+--
+-- Similar to @Reader r = ReaderT r Identity@
+type MultiReader x = MultiReaderT x Identity
 
 class ContainsType a c where
   setHListElem :: a -> HList c -> HList c
   getHListElem :: HList c -> a
 
+-- | All methods must be defined.
+--
+-- The idea is: Any monad stack is instance of @MonadMultiReader a@, iff
+-- the stack contains a @MultiReaderT x@ with /a/ element of /x/.
 class (Monad m) => MonadMultiReader a m where
-  mAsk :: m a
+  mAsk :: m a -- ^ Access to a specific type in the environment.
 
 {-
 it might make seem straightforward to define the following class that
@@ -111,6 +145,10 @@
 instance MonadTrans (MultiReaderT x) where
   lift = MultiReaderT . lift
 
+-- | Adds an element to the environment, thereby transforming a MultiReaderT
+-- carrying an environment with types /(x:xs)/ to a a MultiReaderT with /xs/.
+--
+-- Think "Execute this computation with this additional value as environment".
 withMultiReader :: Monad m
                 => x
                 -> MultiReaderT (Cons x xs) m a
@@ -121,6 +159,14 @@
   put s'
   return a
 
+-- | Adds a heterogenous list of elements to the environment, thereby
+-- transforming a MultiReaderT carrying an environment with values
+-- over types /xs++ys/ to a MultiReaderT over /ys/.
+--
+-- Similar to recursively adding single values with 'withMultiReader'.
+--
+-- Note that /ys/ can be Null; in that case the return value can be
+-- evaluated further using 'evalMultiReaderT'.
 withMultiReaders :: Monad m
                  => HList xs
                  -> MultiReaderT (Append xs ys) m a
@@ -136,18 +182,37 @@
       => MonadMultiReader a (t m) where
   mAsk = lift $ mAsk
 
+-- | A raw extractor of the contained HList (i.e. the complete environment).
+--
+-- For a possible usecase, see 'withMultiReaders'.
 mAskRaw :: Monad m => MultiReaderT a m (HList a)
 mAskRaw = MultiReaderT get
 
+-- | Evaluate a computation over an empty environment.
+--
+-- Because the environment is empty, it does not need to be provided.
+--
+-- If you want to evaluate a computation over any non-Null environment, either
+-- use
+-- 
+-- * 'evalMultiReaderTWithInitial'
+-- * simplify the computation using 'withMultiReader' / 'withMultiReaders',
+--   then use 'evalMultiReaderT' on the result.
 evalMultiReaderT :: Monad m => MultiReaderT Null m a -> m a
 evalMultiReaderT k = evalStateT (runMultiReaderTRaw k) TNull
 
+-- | Evaluate a reader computation with the given environment.
 evalMultiReaderTWithInitial :: Monad m
-                            => HList a
-                            -> MultiReaderT a m b
+                            => HList a            -- ^ The initial state
+                            -> MultiReaderT a m b -- ^ The computation to evaluate
                             -> m b
 evalMultiReaderTWithInitial c k = evalStateT (runMultiReaderTRaw k) c
 
+-- | Map both the return value and the environment of a computation
+-- using the given function.
+--
+-- Note that there is a difference to mtl's ReaderT,
+-- where it is /not/ possible to modify the environment.
 mapMultiReaderT :: (m (a, HList w)
                 -> m' (a', HList w))
                 -> MultiReaderT w m a
diff --git a/src/Control/Monad/MultiState.hs b/src/Control/Monad/MultiState.hs
--- a/src/Control/Monad/MultiState.hs
+++ b/src/Control/Monad/MultiState.hs
@@ -4,17 +4,24 @@
 {-# LANGUAGE OverlappingInstances #-}
 {-# LANGUAGE UndecidableInstances #-}
 
+-- | The multi-valued version of mtl's State / StateT
+-- / MonadState
 module Control.Monad.MultiState
-  ( MultiStateT(..)
+  (
+  -- * MultiStateT
+    MultiStateT(..)
   , MultiStateTNull
   , MultiState
+  -- * MonadMultiState class
   , MonadMultiState(..)
+  -- * functions
   , mGetRaw
   , withMultiState
   , withMultiStates
   , evalMultiStateT
   , evalMultiStateTWithInitial
   , mapMultiStateT
+  -- * re-exports
   , Cons -- re-export that stuff to allow writing type signatures.
   , Null
 ) where
@@ -46,20 +53,49 @@
 
 
 
+-- | A State transformer monad patameterized by:
+--   
+-- * x - The list of types constituting the state,
+-- * m - The inner monad.
+-- 
+-- 'MultiStateT' corresponds to mtl's 'StateT', but can contain
+-- a heterogenous list of types.
+-- 
+-- This heterogenous list is represented using Types.Data.List, i.e:
+-- 
+--   * @'Null'@ - The empty list,
+--   * @'Cons' a b@ - A list where @/a/@ is an arbitrary type
+--     and @/b/@ is the rest list.
+-- 
+-- For example,
+-- 
+-- > MultiStateT (Cons Int (Cons Bool Null)) :: (* -> *) -> (* -> *)
+-- 
+-- is a State wrapper containing the types [Int,Bool].
 newtype MultiStateT x m a = MultiStateT {
   runMultiStateTRaw :: StateT (HList x) m a
 }
 
+-- | A MultiState transformer carrying an empty state.
 type MultiStateTNull = MultiStateT Null
 
-type MultiState x a = MultiStateT x Identity a
+-- | A state monad parameterized by the list of types x of the state to carry.
+--
+-- Similar to @State s = StateT s Identity@
+type MultiState x = MultiStateT x Identity
 
 class ContainsType a c where
   setHListElem :: a -> HList c -> HList c
   getHListElem :: HList c -> a
 
+-- | All methods must be defined.
+--
+-- The idea is: Any monad stack is instance of @MonadMultiState a@, iff
+-- the stack contains a @MultiStateT x@ with /a/ element of /x/.
 class (Monad m) => MonadMultiState a m where
+  -- | state set function for values of type @a@.
   mSet :: a -> m ()
+  -- | state get function for values of type @a@.
   mGet :: m a
 
 instance ContainsType a (Cons a xs) where
@@ -84,20 +120,36 @@
 instance MonadTrans (MultiStateT x) where
   lift = MultiStateT . lift
 
+-- | Adds an element to the state, thereby transforming a MultiStateT over
+-- values with types /(x:xs)/ to a MultiStateT over /xs/.
+--
+-- Think "Execute this computation with this additional value as state".
 withMultiState :: Monad m
-               => x
-               -> MultiStateT (Cons x xs) m a
-               -> MultiStateT xs m a
+               => x                           -- ^ The value to add
+               -> MultiStateT (Cons x xs) m a -- ^ The computation using the
+                                              -- enlarged state
+               -> MultiStateT xs m a          -- ^ An computation using the
+                                              -- smaller state
 withMultiState x k = MultiStateT $ do
   s <- get
   (a, TCons _ s') <- lift $ runStateT (runMultiStateTRaw k) (TCons x s)
   put s'
   return a
 
+-- | Adds a heterogenous list of elements to the state, thereby
+-- transforming a MultiStateT over values with types /xs++ys/ to a MultiStateT
+-- over /ys/.
+--
+-- Similar to recursively adding single values with 'withMultiState'.
+--
+-- Note that /ys/ can be Null; in that case the return value can be
+-- evaluated further using 'evalMultiStateT'.
 withMultiStates :: Monad m
-                => HList xs
-                -> MultiStateT (Append xs ys) m a
-                -> MultiStateT ys m a
+                => HList xs                       -- ^ The list of values to add
+                -> MultiStateT (Append xs ys) m a -- ^ The computation using the
+                                                  --   enlarged state
+                -> MultiStateT ys m a             -- ^ A computation using the
+                                                  -- smaller state
 withMultiStates TNull = id
 withMultiStates (TCons x xs) = withMultiStates xs . withMultiState x
 
@@ -111,18 +163,38 @@
   mSet = lift . mSet
   mGet = lift $ mGet
 
+-- | Evaluate an empty state computation.
+--
+-- Because the state is empty, no initial state must be provided.
+--
+-- Currently it is not directly possible to extract the final state of a
+-- computation (similar to @execStateT@ and @runStateT@ for mtl's StateT),
+-- but you can use 'mGetRaw' if you need such functionality.
+--
+-- If you want to evaluate a computation over any non-Null state, either
+-- use
+-- 
+-- * 'evalMultiStateTWithInitial'
+-- * simplify the computation using 'withMultiState' / 'withMultiStates',
+--   then use 'evalMultiStateT' on the result.
 evalMultiStateT :: Monad m => MultiStateT Null m a -> m a
 evalMultiStateT k = evalStateT (runMultiStateTRaw k) TNull
 
+-- | Evaluate a state computation with the given initial state.
 evalMultiStateTWithInitial :: Monad m
-                           => HList a
-                           -> MultiStateT a m b
+                           => HList a           -- ^ The initial state
+                           -> MultiStateT a m b -- ^ The computation to evaluate
                            -> m b
 evalMultiStateTWithInitial c k = evalStateT (runMultiStateTRaw k) c
 
+-- | A raw extractor of the contained HList (i.e. the complete state).
+--
+-- For a possible usecase, see 'withMultiStates'.
 mGetRaw :: Monad m => MultiStateT a m (HList a)
 mGetRaw = MultiStateT get
 
+-- | Map both the return value and the state of a computation
+-- using the given function.
 mapMultiStateT :: (m (a, HList w) -> m' (a', HList w))
                -> MultiStateT w m  a
                -> MultiStateT w m' a'
diff --git a/src/Data/HList/HList.hs b/src/Data/HList/HList.hs
--- a/src/Data/HList/HList.hs
+++ b/src/Data/HList/HList.hs
@@ -1,8 +1,12 @@
 {-# LANGUAGE GADTs #-}
 {-# LANGUAGE TypeFamilies #-}
 
-module Data.HList.HList(
-  HList(..)
+-- | A GADT HList implementation
+--
+-- Probably exists somewhere else already, but why add a dependency
+-- for something so simple.
+module Data.HList.HList
+  ( HList(..)
 ) where
 
 
@@ -10,6 +14,7 @@
 import Prelude hiding (reverse)
 
 import Types.Data.List ( Cons, Null )
+import Data.Monoid
 
 
 
@@ -22,3 +27,15 @@
 
 instance (Show a, Show (HList b)) => Show (HList (Cons a b)) where
   show (TCons x y) = "(" ++ show x ++ "," ++ show y ++ ")"
+
+instance Monoid (HList Null) where
+  mempty = TNull
+  mappend _ _ = TNull
+
+instance (Monoid x, Monoid (HList xs))
+      => Monoid (HList (Cons x xs))
+  where
+    mempty = TCons mempty mempty
+    mappend (TCons x1 xs1) (TCons x2 xs2) =
+      TCons (x1 `mappend` x2)
+            (xs1 `mappend` xs2)
