diff --git a/MHask.cabal b/MHask.cabal
--- a/MHask.cabal
+++ b/MHask.cabal
@@ -1,36 +1,48 @@
--- Initial MHask.cabal generated by cabal init.  For further documentation,
---  see http://haskell.org/cabal/users-guide/
-
 name:                MHask
-version:             0.1.0.0
+version:             0.2.0.0
 synopsis:            The category of monads
-category:            Control
 description:         
   MHask is the category where
   .
-  * The objects are Haskell types of kind (* -> *) that have an instance of Monad
-  * An arrow from object m to object n is a Haskell function of the form (forall x. m x -> n x)
+  * The objects are Haskell types of kind @(* → *)@ that have an instance of `Prelude.Monad'
+  .
+  * An arrow from object m to object n is a Haskell function of the form @(forall x. m x → n x)@
+  .
   * Arrow composition is merely a specialization of Haskell function composition
-  * The identity arrow for the object m is the id function in Haskell, specialized to (forall x. m x -> m x)
   .
-  Functor should actually be called Endofunctor, because if m is an object in MHask,
-  then an instance t of Functor can transform object m into object (t m).
-  You will see *a lot* of constraints in the type classes defined herein.
-  Though daunting at first, you will soon realize that they are *all* Prelude.Monad constraints,
-  and their interpretation is simply a guarantee that
-  "the objects of MHask are types of kind (* -> *) that have an instance of Monad."
+  * The identity arrow for the object m is the `Prelude.id' function in Haskell,
+  specialized to @(forall x. m x → m x)@
+  .
+  It is assumed that any instances of the classes provided here also have an instance
+  for Monad of the form @instance (Monad m) ⇒ Monad (t m)@, thus guaranteeing that @(t m)@
+  (or @(t i j m)@ for the indexed types) is always a Monad. If it were valid Haskell, I'd write:
+  .
+  > class (forall m. Monad m ⇒ Monad (t m)) ⇒ Functor t
+  .
+  'MHask.Functor.Functor' should actually be called Endofunctor, because if m is an object in MHask,
+  then an instance t of `Functor' can map object m to object (t m), and arrows from 
+  m to n get mapped to arrows from (t m) to (t n).
 
+
 homepage:            https://github.com/DanBurton/MHask#readme
 license:             BSD3
 license-file:        LICENSE
 author:              Dan Burton
 maintainer:          danburton.email@gmail.com
--- copyright:           
--- category:            
+category:            Control
 build-type:          Simple
 cabal-version:       >=1.8
 
+source-repository head
+  type:     git
+  location: git://github.com/DanBurton/MHask.git
+
+source-repository this
+  type:     git
+  location: git://github.com/DanBurton/MHask.git
+  tag:      MHask-0.2.0.0
+
 library
   exposed-modules:     MHask, MHask.Comonad, MHask.Monad, MHask.Copointed, MHask.Pointed, MHask.Util, MHask.Functor, MHask.Indexed.Comonad, MHask.Indexed.Monad, MHask.Indexed.Copointed, MHask.Indexed.Pointed, MHask.Indexed.Functor
-  -- other-modules:       
-  build-depends:       base == 4.6.*, transformers >= 0.3
+
+  build-depends:       base >= 2 && < 4.7, transformers >= 0.3
diff --git a/MHask.hs b/MHask.hs
--- a/MHask.hs
+++ b/MHask.hs
@@ -1,16 +1,39 @@
 
-module MHask (module MHask) where
+-- | Various abstractions in the category of MHask.
+-- This re-exports everything, and should be imported
+-- qualified so that the operations and classes
+-- do not clash with their Hask counterparts.
+-- 
+-- > import qualified MHask
+module MHask (
+  -- * Prelimiaries
+  module MHask.Util,
 
-import MHask.Util as MHask
+  -- * Classes
+  module MHask.Functor,
+  module MHask.Pointed,
+  module MHask.Monad,
+  module MHask.Copointed,
+  module MHask.Comonad,
 
-import qualified MHask.Functor as MHask
-import qualified MHask.Pointed as MHask
-import qualified MHask.Monad   as MHask
-import qualified MHask.Copointed as MHask
-import qualified MHask.Comonad as MHask
+  -- * Indexed Classes
+  module MHask.Indexed.Functor,
+  module MHask.Indexed.Pointed,
+  module MHask.Indexed.Monad,
+  module MHask.Indexed.Copointed,
+  module MHask.Indexed.Comonad,
+  ) where
 
-import qualified MHask.Indexed.Functor as MHask
-import qualified MHask.Indexed.Pointed as MHask
-import qualified MHask.Indexed.Monad   as MHask
-import qualified MHask.Indexed.Copointed as MHask
-import qualified MHask.Indexed.Comonad as MHask
+import MHask.Util
+
+import MHask.Functor
+import MHask.Pointed
+import MHask.Monad
+import MHask.Copointed
+import MHask.Comonad
+
+import MHask.Indexed.Functor
+import MHask.Indexed.Pointed
+import MHask.Indexed.Monad
+import MHask.Indexed.Copointed
+import MHask.Indexed.Comonad
diff --git a/MHask/Comonad.hs b/MHask/Comonad.hs
--- a/MHask/Comonad.hs
+++ b/MHask/Comonad.hs
@@ -2,27 +2,31 @@
 {-# LANGUAGE Rank2Types #-}
 {-# LANGUAGE DefaultSignatures #-}
 
--- Compare to comonad.Control.Comonad (Comonad)
+-- | Compare to comonad.Control.Comonad (Comonad)
 module MHask.Comonad where
 
-import MHask.Util
 
-import Control.Monad.Trans.State
-import Control.Monad.Trans.Reader
-import Control.Monad.Trans.Writer
 
+import MHask.Util
+
 import qualified MHask.Functor as MHask
 import qualified MHask.Copointed as MHask
 
 
+-- | Dual of "MHask.Monad"
 class (MHask.Copointed t) => Comonad t where
-  extend :: (Monad m, Monad n, Monad (t m), Monad (t n))
-    => (t m ~> n) -> (t m ~> t n)
-  default extend :: (Monad m, Monad n, Monad (t m), Monad (t n),
-                     Monad (t (t m)))
-    => (t m ~> n) -> (t m ~> t n)
-  extend f = duplicate ~> MHask.fmap f
-
-  duplicate :: (Monad m, Monad (t m), Monad (t (t m)))
-    => t m ~> t (t m)
+  duplicate :: (Monad m)
+    => t (t m) <~ t m
+  default duplicate :: (Monad m, Monad (t m))
+    => t (t m) <~ t m
   duplicate = extend id
+
+  extend :: (Monad m, Monad n)
+    => (m <~ t n) -> (t m <~ t n)
+  default extend ::
+    (Monad m, Monad n,
+     Monad (t m), Monad (t n),
+     Monad (t (t n)))
+    => (m <~ t n) -> (t m <~ t n)
+  extend f = MHask.fmap f ~<~ duplicate
+
diff --git a/MHask/Copointed.hs b/MHask/Copointed.hs
--- a/MHask/Copointed.hs
+++ b/MHask/Copointed.hs
@@ -2,31 +2,34 @@
 {-# LANGUAGE Rank2Types #-}
 
 
--- Compare to todo.Copointed
+-- | Compare to comonad.Control.Comonad (Copointed)
 module MHask.Copointed where
 
+
 import MHask.Util
 
+import Data.Monoid
+import Control.Monad (liftM)
 import Control.Monad.Trans.State
 import Control.Monad.Trans.Reader
 import Control.Monad.Trans.Writer
 
-import Data.Monoid
-import Control.Monad (liftM)
-
 import qualified MHask.Functor as MHask
 
 
+
+-- | The dual of "MHask.Pointed"
 class (MHask.Functor t) => Copointed t where
-  extract :: (Monad m, Monad (t m))
-    => t m ~> m
+  extract :: (Monad m)
+    => m <~ t m
 
 
-instance Copointed (WriterT w) where
-  extract = liftM fst . runWriterT
-
 instance (Monoid s) => Copointed (StateT s) where
   extract = flip evalStateT mempty
 
 instance (Monoid r) => Copointed (ReaderT r) where
   extract = flip runReaderT mempty
+
+instance Copointed (WriterT w) where
+  extract = liftM fst . runWriterT
+
diff --git a/MHask/Functor.hs b/MHask/Functor.hs
--- a/MHask/Functor.hs
+++ b/MHask/Functor.hs
@@ -1,7 +1,8 @@
 {-# LANGUAGE TypeOperators #-}
 {-# LANGUAGE Rank2Types #-}
 
--- Compare to base.Prelude.Functor (Functor)
+
+-- | Compare to base.Prelude.Functor (Functor)
 module MHask.Functor where
 
 import Prelude hiding (Functor, fmap)
@@ -12,8 +13,14 @@
 import Control.Monad.Trans.Writer
 
 
+
+-- | Functor is its own dual.
 class Functor t where
-  fmap :: (Monad m, Monad n, Monad (t m), Monad (t n))
+  -- | Flipping the arrows on fmap's type signature
+  -- is just the same type signature in disguise.
+  -- 
+  -- > (m <~ n) -> (t m <~ t n)
+  fmap :: (Monad m, Monad n)
     => (m ~> n) -> (t m ~> t n)
 
 
diff --git a/MHask/Indexed/Comonad.hs b/MHask/Indexed/Comonad.hs
--- a/MHask/Indexed/Comonad.hs
+++ b/MHask/Indexed/Comonad.hs
@@ -2,33 +2,31 @@
 {-# LANGUAGE Rank2Types #-}
 {-# LANGUAGE DefaultSignatures #-}
 
--- Compare to indexed.Control.Comonad.Indexed (IxComonad)
+-- | Compare to indexed.Control.Comonad.Indexed (IxComonad)
 module MHask.Indexed.Comonad where
 
-import MHask.Util
 
-import Control.Monad.Trans.State
-import Control.Monad.Trans.Reader
-import Control.Monad.Trans.Writer
 
+import MHask.Util
+
 import qualified MHask.Indexed.Functor as MHask
 import qualified MHask.Indexed.Copointed as MHask
 
-
+-- | Indexed version of "MHask.Comonad".
+-- Dual of "MHask.Indexed.Monad"
 class (MHask.IxCopointed t) => IxComonad t where
-  iextend :: (Monad m, Monad n,
-             Monad (t i j m), Monad (t j k n), Monad (t i k m))
-    => (t j k m ~> n) -> (t i k m ~> t i j n)
-  default iextend :: (Monad m, Monad n,
-             Monad (t i j m), Monad (t j k n), Monad (t i k m),
-             Monad (t i j (t j k m)), Monad (t j k m), Monad (t i j n))
-    => (t j k m ~> n) -> (t i k m ~> t i j n)
-  iextend f = iduplicate ~> MHask.imap f
+  iduplicate :: (Monad m)
+    => t i j (t j k m) <~ t i k m
+  default iduplicate :: (Monad m, Monad (t j k m))
+    => t i j (t j k m) <~ t i k m
+  iduplicate = iextend id
 
-  iduplicate :: (Monad m, Monad (t i k m), Monad (t i j (t j k m)))
-    => t i k m ~> t i j (t j k m)
+  iextend :: (Monad m, Monad n)
+    => (m <~ t j k n) -> (t i j m <~ t i k n)
+  default iextend ::
+    (Monad m, Monad n,
+     Monad (t i j m), Monad (t j k n), Monad (t i k n),
+     Monad (t i j (t j k n)))
+    => (m <~ t j k n) -> (t i j m <~ t i k n)
+  iextend f = MHask.imap f ~<~ iduplicate
 
-  default iduplicate :: (Monad m, Monad (t i k m), Monad (t i j (t j k m)),
-                          (Monad (t j k (t j k m))), (Monad (t i j m)),  (Monad (t j k m)))
-    => t i k m ~> t i j (t j k m)
-  iduplicate = iextend id
diff --git a/MHask/Indexed/Copointed.hs b/MHask/Indexed/Copointed.hs
--- a/MHask/Indexed/Copointed.hs
+++ b/MHask/Indexed/Copointed.hs
@@ -2,21 +2,27 @@
 {-# LANGUAGE Rank2Types #-}
 {-# LANGUAGE DefaultSignatures #-}
 
--- Compare to indexed.Data.Functor.Indexed (IxCopointed)
+-- | Compare to indexed.Data.Functor.Indexed (IxCopointed)
 module MHask.Indexed.Copointed where
 
+
 import MHask.Util
 
-import Control.Monad.Trans.State
-import Control.Monad.Trans.Reader
-import Control.Monad.Trans.Writer
 
+
+
+
+
+
 import qualified MHask.Copointed as MHask
 import qualified MHask.Indexed.Functor as MHask
 
+-- | The indexed version of "MHask.Copointed".
+-- The dual of "MHask.Indexed.Pointed".
 class (MHask.IxFunctor t) => IxCopointed t where
-  iextract :: (Monad m, Monad (t i i m))
-    => t i i m ~> m
-  default iextract :: (Monad m, Monad (t i i m), MHask.Copointed (t i i))
-    => t i i m ~> m
+  iextract :: (Monad m)
+    => m <~ t i i m
+  default iextract :: (Monad m,
+                       MHask.Copointed (t i i))
+    => m <~ t i i m
   iextract = MHask.extract
diff --git a/MHask/Indexed/Functor.hs b/MHask/Indexed/Functor.hs
--- a/MHask/Indexed/Functor.hs
+++ b/MHask/Indexed/Functor.hs
@@ -2,7 +2,7 @@
 {-# LANGUAGE Rank2Types #-}
 {-# LANGUAGE DefaultSignatures #-}
 
--- Compare to indexed.Data.Functor.Indexed (IxFunctor)
+-- | Compare to indexed.Data.Functor.Indexed (IxFunctor)
 module MHask.Indexed.Functor where
 
 import MHask.Util
@@ -13,10 +13,16 @@
 
 import qualified MHask.Functor as MHask
 
+-- | The indexed version of "MHask.Functor".
+-- IxFunctor is its own dual.
 class IxFunctor t where
-  imap :: (Monad m, Monad n, Monad (t i j m), Monad (t i j n))
+  -- | Flipping the arrows on imap's type signature
+  -- is just the same type signature in disguise.
+  -- 
+  -- > (m <~ n) -> (t i j m <~ t i j n)
+  imap :: (Monad m, Monad n)
     => (m ~> n) -> (t i j m ~> t i j n)
-  default imap :: (Monad m, Monad n, Monad (t i j m), Monad (t i j n),
-                     MHask.Functor (t i j))
+  default imap :: (Monad m, Monad n,
+                   MHask.Functor (t i j))
     => (m ~> n) -> (t i j m ~> t i j n)
   imap = MHask.fmap
diff --git a/MHask/Indexed/Monad.hs b/MHask/Indexed/Monad.hs
--- a/MHask/Indexed/Monad.hs
+++ b/MHask/Indexed/Monad.hs
@@ -2,31 +2,31 @@
 {-# LANGUAGE Rank2Types #-}
 {-# LANGUAGE DefaultSignatures #-}
 
--- Compare to indexed.Control.Monad.Indexed (IxMonad)
+-- | Compare to indexed.Control.Monad.Indexed (IxMonad)
 module MHask.Indexed.Monad where
 
-import MHask.Util
 
-import Control.Monad.Trans.State
-import Control.Monad.Trans.Reader
-import Control.Monad.Trans.Writer
 
-import qualified MHask.Monad as MHask
+import MHask.Util
+
 import qualified MHask.Indexed.Pointed as MHask
 import qualified MHask.Indexed.Functor as MHask
 
+-- | Indexed version of "MHask.Monad".
+-- Dual of "MHask.Indexed.Comonad"
 class (MHask.IxPointed t) => IxMonad t where
-  ijoin :: (Monad m, Monad (t i j (t j k m)), Monad (t i k m))
+  ijoin :: (Monad m)
     => t i j (t j k m) ~> t i k m
-  default ijoin :: (Monad m, Monad (t i j (t j k m)), Monad (t i k m),
-                     Monad (t j k m))
+  default ijoin :: (Monad m, Monad (t j k m))
     => t i j (t j k m) ~> t i k m
   ijoin = ibind id
 
-
-  ibind :: (Monad m, Monad (t i j m), Monad n, Monad (t j k n))
+  ibind :: (Monad m, Monad n)
     => (m ~> t j k n) -> (t i j m ~> t i k n)
-  default ibind :: (Monad m, Monad (t i j m), Monad n, Monad (t j k n),
-             Monad (t i k n), Monad (t i j (t j k n)))
+  default ibind ::
+    (Monad m, Monad n,
+     Monad (t i j m), Monad (t j k n), Monad (t i k n),
+     Monad (t i j (t j k n)))
     => (m ~> t j k n) -> (t i j m ~> t i k n)
-  ibind f = MHask.imap f ~> ijoin
+  ibind f = MHask.imap f ~>~ ijoin
+
diff --git a/MHask/Indexed/Pointed.hs b/MHask/Indexed/Pointed.hs
--- a/MHask/Indexed/Pointed.hs
+++ b/MHask/Indexed/Pointed.hs
@@ -2,21 +2,27 @@
 {-# LANGUAGE Rank2Types #-}
 {-# LANGUAGE DefaultSignatures #-}
 
--- Compare to indexed.Data.Functor.Indexed (IxPointed)
+-- | Compare to indexed.Data.Functor.Indexed (IxPointed)
 module MHask.Indexed.Pointed where
 
+
 import MHask.Util
 
-import Control.Monad.Trans.State
-import Control.Monad.Trans.Reader
-import Control.Monad.Trans.Writer
 
+
+
+
+
+
 import qualified MHask.Pointed as MHask
 import qualified MHask.Indexed.Functor as MHask
 
+-- | The indexed version of "MHask.Pointed".
+-- The dual of "MHask.Indexed.Copointed".
 class (MHask.IxFunctor t) => IxPointed t where
-  ireturn :: (Monad m, Monad (t i i m))
+  ireturn :: (Monad m)
     => m ~> t i i m
-  default ireturn :: (Monad m, Monad (t i i m), MHask.Pointed (t i i))
+  default ireturn :: (Monad m,
+                      MHask.Pointed (t i i))
     => m ~> t i i m
   ireturn = MHask.return
diff --git a/MHask/Monad.hs b/MHask/Monad.hs
--- a/MHask/Monad.hs
+++ b/MHask/Monad.hs
@@ -2,7 +2,7 @@
 {-# LANGUAGE Rank2Types #-}
 {-# LANGUAGE DefaultSignatures #-}
 
--- Compare to base.Prelude.Monad
+-- | Compare to base.Prelude (Monad)
 module MHask.Monad where
 
 import Prelude hiding (Monad, join)
@@ -12,19 +12,20 @@
 import qualified MHask.Functor as MHask
 import qualified MHask.Pointed as MHask
 
-import Control.Monad.Trans.State
-import Control.Monad.Trans.Reader
-import Control.Monad.Trans.Writer
 
-
+-- | Dual of "MHask.Comonad"
 class (MHask.Pointed t) => Monad t where
-  join :: (P.Monad m, P.Monad (t m), P.Monad (t (t m)))
+  join :: (P.Monad m)
     => t (t m) ~> t m
+  default join :: (P.Monad m, P.Monad (t m))
+    => t (t m) ~> t m
   join = bind id
 
-  bind :: (P.Monad m, P.Monad (t m), P.Monad n, P.Monad (t n))
+  bind :: (P.Monad m, P.Monad n)
     => (m ~> t n) -> (t m ~> t n)
-  default bind :: (P.Monad m, P.Monad (t m), P.Monad n, P.Monad (t n),
-                   P.Monad (t (t n)))
+  default bind ::
+    (P.Monad m, P.Monad n,
+     P.Monad (t m), P.Monad (t n),
+     P.Monad (t (t n)))
     => (m ~> t n) -> (t m ~> t n)
-  bind f = MHask.fmap f ~> join
+  bind f = MHask.fmap f ~>~ join
diff --git a/MHask/Pointed.hs b/MHask/Pointed.hs
--- a/MHask/Pointed.hs
+++ b/MHask/Pointed.hs
@@ -1,7 +1,8 @@
 {-# LANGUAGE TypeOperators #-}
 {-# LANGUAGE Rank2Types #-}
 
--- no relevant comparison
+
+-- | Equivalent to transformers.Control.Monad.Trans.Class (MonadTrans)
 module MHask.Pointed where
 
 import Prelude hiding (return)
@@ -12,17 +13,16 @@
 import Control.Monad.Trans.State
 import Control.Monad.Trans.Reader
 import Control.Monad.Trans.Writer
-import Control.Monad.Trans.Class
 
 import qualified MHask.Functor as MHask
 
-class (MHask.Functor t) => Pointed t where
-  return :: (Monad m, Monad (t m))
-    => (m ~> t m)
 
 
--- This is basically MonadTrans
--- lift = MHask.return
+-- | The dual of "MHask.Copointed"
+class (MHask.Functor t) => Pointed t where
+  return :: (Monad m)
+    => m ~> t m
+
 
 instance Pointed (StateT s) where
   return mx = StateT $ \s -> liftM (\x -> (x, s)) mx
diff --git a/MHask/Util.hs b/MHask/Util.hs
--- a/MHask/Util.hs
+++ b/MHask/Util.hs
@@ -1,9 +1,44 @@
 {-# LANGUAGE TypeOperators #-}
 {-# LANGUAGE Rank2Types #-}
 
+-- | This module sets the stage for the rest of the package.
+-- It defines a type synonym @~>@ which cleans up the
+-- type signatures,
+-- and  @~>~@ which is used in the default implementation
+-- of bind. These represent the type of arrows and arrow composition
+-- in MHask, respectively.
+-- 
+-- By using @~>@, type signatures for the MHask class operations
+-- can be easily compared to their Hask counterparts. However,
+-- as a reminder that you are dealing with Monads, where
+-- typically you would see @a@ and @b@ in the Hask counterpart,
+-- you will instead see @m@ and @n@, and where you would
+-- typically see @m@ or @w@, you will instead see @t@,
+-- as a mnemonic for Monad transformer.
+-- 
+-- For illustrative purposes, this module also provides
+-- @<~@ and @~<~@, to clearly illustrate how duals are
+-- nothing more than just \"flipping the arrows\".
+-- You are encouraged to compare docs or even source files
+-- to see just how similar they are, all the way down
+-- to default implementations.
 module MHask.Util where
 
+-- | The @~>@ type represents arrows in the
+-- category of MHask. 
 type m ~> n = forall x. m x -> n x
 
-(~>) :: (Monad a, Monad b, Monad c) => (a ~> b) -> (b ~> c) -> (a ~> c)
-f1 ~> f2 = f2 . f1
+-- | It's just @~>@ flipped.
+-- 
+-- > type m <~ n = n ~> m
+type m <~ n = n ~> m
+
+-- | Left-to-right composition of arrows in MHask.
+(~>~) :: (Monad a, Monad b, Monad c) => (a ~> b) -> (b ~> c) -> (a ~> c)
+f1 ~>~ f2 = f2 . f1
+
+-- | It's just @~>~@ flipped.
+-- 
+-- > (~<~) = flip (~>~)
+(~<~) :: (Monad a, Monad b, Monad c) => (c <~ b) -> (b <~ a) -> (c <~ a)
+(~<~) = flip (~>~)
