diff --git a/Test/OITestGenerator.hs b/Test/OITestGenerator.hs
--- a/Test/OITestGenerator.hs
+++ b/Test/OITestGenerator.hs
@@ -1,5 +1,116 @@
 {-# LANGUAGE TemplateHaskell #-}
 
+{-|
+Module      : Test.OITestGenerator
+Description : Generate operation invariance tests from axioms at compile time
+Copyright   : (c) Tobias Gödderz, 2014
+License     : BSD3
+Maintainer  : haskell@tobias.goedderz.info
+Stability   : provisional
+Portability : non-portable (Template-Haskell)
+
+("QuickCheck"-)tests for data types are often formulated as equations, i.e.
+
+>rev_test :: Property
+>rev_test = property $ \xs ys -> reverse ys ++ reverse xs == reverse (xs ++ ys)
+
+. There are assumptions everyone usually makes about the behaviour of @(==)@,
+but does not necessarily think about:
+
+ 1. @x == x@ should always be 'True' (reflexivity).
+
+ 2. if @x == y@ is 'True', @y == x@ should also be 'True' (symmetry).
+
+ 3. if @x == y@ and @y == z@ are 'True', @x == z@ should also be 'True'
+    (transitivity).
+
+ 4. if @x == y@ is true, @f x == f y@ should also be 'True' (congruence or
+    operation invariance).
+
+It is unlikely to accidentally write an 'Eq' instance that does not satisfy 1-3.
+Operation invariance however is fickle, as it also implies sane behaviour of all
+functions on the data type.
+
+This framework takes "QuickCheck"-like equality tests (called axioms) of a data
+type and functions on the data type (called operations), and uses them to
+generate the corresponding "QuickCheck" tests, as well as additional operation
+invariance tests.
+
+For example, given a queue of integers 'IntQueue' with the following operations.
+
+>empty   :: IntQueue                    -- create an empty queue
+>isEmpty :: IntQueue -> Bool            -- test if a given queue is empty
+>enqueue :: Int -> IntQueue -> IntQueue -- enqueue an integer to a queue
+>dequeue :: IntQueue -> IntQueue        -- dequeue the first element of a queue
+>front   :: IntQueue -> Int             -- get the first element of a queue
+
+A "QuickCheck" test for this might be
+
+>property $ \x q -> not (isEmpty q) ==> dequeue (enqueue x q) == enqueue x (dequeue q)
+
+while this would be formulated as an axiom as follows:
+
+>q6 x q = not (isEmpty q) ===> dequeue (enqueue x q) =!= enqueue x (dequeue q)
+
+Assuming you wrote six axioms @q1@-@q6@, the six corresponding "QuickCheck"
+tests can be generated by 'generate_basic_tests'.
+
+
+@
+{\-\# LANGUAGE TemplateHaskell \#-\}
+...
+queue_basic_tests :: [Property]
+queue_basic_tests = $(
+    let axs = map axiom ['q1, 'q2, 'q3, 'q4, 'q5, 'q6]
+    in generate_basic_tests axs)
+@
+
+The single quotes preceding @q1@ to @q6@ quote each following name
+as a Template Haskell 'Language.Haskell.TH.Syntax.Name'. Note that @$(...)@ is
+a Template Haskell splice and will be evaluated during compile time. Because of
+this, you might not refer to declarations of the same module except by name
+(this is called the stage restriction), which is the motivation for the @let ...
+in ...@ construct.
+
+Additional operation invariance tests can be generated with 'generate_oi_tests'.
+
+>may_dequeue :: IntQueue -> Bool
+>may_dequeue = not . isEmpty
+>
+>may_front :: IntQueue -> Bool
+>may_front = not . isEmpty
+>
+>adt_oi_tests :: [Property]
+>adt_oi_tests = $(
+>    let ops = [ op 'empty, op 'enqueue, op 'isEmpty
+>              , op 'dequeue `withConstraint` 'may_dequeue
+>              , op 'front `withConstraint` 'may_front
+>              ]
+>        axs = map axiom ['q1, 'q2, 'q3, 'q4, 'q5, 'q6 ]
+>    in generate_oi_tests axs ops)
+
+For every operation @f@ and every axiom @lhs =!= rhs@, a test @f lhs == f rhs@
+will be generated if it is typecorrect. Note that polymorphic types aren't
+supported yet, but you can simply rename and specialize them, i.e.
+
+>reverse_ints :: [Int] -> [Int]
+>reverse_ints = reverse
+
+and test the renamed function. Besides typechecking, 'generate_oi_tests' takes
+care of
+
+ * passing axiom arguments, e.g. @f@ and @ax x = lhs x =!= rhs x@ will get
+   translated to @\x -> f (lhs x) == f (rhs x)@.
+
+ * multiple operation arguments, e.g. for an @f :: A -> A -> B -> C@ and an
+   axiom with result @A@, both tests @f lhs y z == f rhs y z@ and @f x lhs z ==
+   f x rhs z@ will be generated.
+
+ * translating constraints of both axioms and operations to '==>'. Axiom
+   constraints are specified via '===>', while operation constraints are
+   specified via 'withConstraint'.
+
+-}
 module Test.OITestGenerator (
     AxiomResult, (===>), (=!=),
     Axiom, axiom,
@@ -29,28 +140,28 @@
 --
 -- It returns an expression of type @[Property]@, i.e.
 --
--- > $(generate_basic_tests axs) :: [Property]
+-- >$(generate_basic_tests axs) :: [Property]
 generate_basic_tests :: [Axiom] -> ExpQ
 generate_basic_tests = liftM ListE . mapM gen_basic_test
 
 -- | Generate all operation invariance tests that typecheck. For example, given
 -- an operation
 --
--- > f :: A -> A -> B -> C
+-- >f :: A -> A -> B -> C
 --
 -- and an axiom
 --
--- > ax :: D -> AxiomResult A
--- > ax x = lhs x =!= rhs x
+-- >ax :: D -> AxiomResult A
+-- >ax x = lhs x =!= rhs x
 --
 -- the following tests are generated:
 --
--- > property $ \y2 y3 -> f (lhs x) y2 y3 == f (rhs x) y2 y3
--- > property $ \y1 y3 -> f y1 (lhs x) y3 == f y1 (rhs x) y3
+-- >property $ \y2 y3 -> f (lhs x) y2 y3 == f (rhs x) y2 y3
+-- >property $ \y1 y3 -> f y1 (lhs x) y3 == f y1 (rhs x) y3
 --
 -- but not
 --
--- > property $ \y1 y2 -> f y1 y2 (lhs x) == f y1 y2 (rhs x)
+-- >property $ \y1 y2 -> f y1 y2 (lhs x) == f y1 y2 (rhs x)
 --
 -- because of the types.
 --
@@ -58,7 +169,7 @@
 --
 -- It returns an expression of type @[Property]@, i.e.
 --
--- > $(generate_oi_tests axs ops) :: [Property]
+-- >$(generate_oi_tests axs ops) :: [Property]
 generate_oi_tests :: [Axiom] -> [Op] -> ExpQ
 generate_oi_tests = gen_tests
 
@@ -66,7 +177,7 @@
 --
 -- It returns an expression of type @[Property]@, i.e.
 --
--- > $(generate_axiom's_tests ax ops) :: [Property]
+-- >$(generate_axiom's_tests ax ops) :: [Property]
 generate_axiom's_tests :: Axiom -> [Op] -> ExpQ
 generate_axiom's_tests ax = gen_tests [ax]
 
@@ -78,7 +189,7 @@
 --
 -- It returns an expression of type @Property@, i.e.
 --
--- > $(generate_single_test ax op) :: Property
+-- >$(generate_single_test ax op) :: Property
 generate_single_test :: Axiom -> Op -> ExpQ
 generate_single_test ax opn = op2opArgs opn
     >>= filter_Ops ax
@@ -110,12 +221,12 @@
 -- The first argument can replace the default function generating a name for
 -- each test, which is
 --
--- > \opn argi ax -> opn ++ show argi ++ "_" ++ ax
+-- >\opn argi ax -> opn ++ show argi ++ "_" ++ ax
 --
 -- . An example output looks like this:
 --
--- > enqueue1_q3 :: Property
--- > enqueue1_q3 = $(generate_single_test (axiom 'q3) (op 'enqueue `only` 1))
+-- >enqueue1_q3 :: Property
+-- >enqueue1_q3 = $(generate_single_test (axiom 'q3) (op 'enqueue `only` 1))
 show_all_tests :: Maybe (String -> Int -> String -> String) -> [Name] -> [Name] -> ExpQ
 show_all_tests Nothing axs ops = show_all_tests (Just def_test_name) axs ops
 show_all_tests (Just fun) axs ops =
diff --git a/Test/OITestGenerator/Axiom.hs b/Test/OITestGenerator/Axiom.hs
--- a/Test/OITestGenerator/Axiom.hs
+++ b/Test/OITestGenerator/Axiom.hs
@@ -21,13 +21,13 @@
 -- | Combine the results of the left- and right-hand sides of an axiom.
 --   A simple example is
 --
---   > q1 :: AxiomResult Bool
---   > q1 = isEmpty empty =!= True
+--   >q1 :: AxiomResult Bool
+--   >q1 = isEmpty empty =!= True
 --
 --   while an axiom with variables would be written as a function like this:
 --
---   > q2 :: Int -> IntQueue -> AxiomResult Bool
---   > q2 x q = isEmpty (enqueue x q) =!= False
+--   >q2 :: Int -> IntQueue -> AxiomResult Bool
+--   >q2 x q = isEmpty (enqueue x q) =!= False
 (=!=) :: a -> a -> AxiomResult a
 lhs =!= rhs = AxiomResult (True, lhs, rhs)
 
@@ -38,8 +38,8 @@
 --
 --   Example usage:
 --
--- > q4 :: Int -> IntQueue -> AxiomResult Int
--- > q4 x q = not (isEmpty q) ===> front (enqueue x q) =!= front q
+-- >q4 :: Int -> IntQueue -> AxiomResult Int
+-- >q4 x q = not (isEmpty q) ===> front (enqueue x q) =!= front q
 (===>) :: Bool -> AxiomResult a -> AxiomResult a
 cond ===> AxiomResult (cond', lhs, rhs) = AxiomResult (cond && cond', lhs, rhs)
 
@@ -61,11 +61,11 @@
 
 -- | 'Axiom' constructor. Takes a 'Language.Haskell.TH.Syntax.Name', i.e.
 --
--- > axiom 'q1
+-- >axiom 'q1
 --
 -- or
 --
--- > map axiom ['q1, 'q2, 'q3]
+-- >map axiom ['q1, 'q2, 'q3]
 --
 -- .
 axiom :: Name -> Axiom
diff --git a/Test/OITestGenerator/Op.hs b/Test/OITestGenerator/Op.hs
--- a/Test/OITestGenerator/Op.hs
+++ b/Test/OITestGenerator/Op.hs
@@ -49,7 +49,7 @@
 --
 -- Example:
 --
--- > op 'dequeue `but` arg 1
+-- >op 'dequeue `but` arg 1
 but :: Op -> Arg -> Op
 but op' excl = modify argis (liftM $ delete excl) op'
 
@@ -57,7 +57,7 @@
 --
 -- Example:
 --
--- > op 'dequeue `only` arg 1
+-- >op 'dequeue `only` arg 1
 only :: Op -> Arg -> Op
 only op' argi = modify argis (>>= \args ->
         if argi `elem` args
diff --git a/qc-oi-testgenerator.cabal b/qc-oi-testgenerator.cabal
--- a/qc-oi-testgenerator.cabal
+++ b/qc-oi-testgenerator.cabal
@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                qc-oi-testgenerator
-version:             1.2.0.1
+version:             1.2.0.2
 synopsis:            Compile time generation of operation invariance tests for QuickCheck
 -- description:
 --homepage:            http://tobias.goedderz.info/haskell/qc-oi-testgenerator/
