diff --git a/CHANGES b/CHANGES
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,11 @@
+-*- mode: org -*-
+
+0.3.1.1
+=======
+
+- Adding a little bit of documentation and better documentation in the
+  Description field.
+
 0.3.1.0
 =======
 
diff --git a/README.md b/README.md
deleted file mode 100644
--- a/README.md
+++ /dev/null
@@ -1,38 +0,0 @@
-Welcome!
-=====
-
-Prizm is a haskell library for dealing with colors. Please contribute!
-
-My inspiration for writing this was Sass and Bourbon, both implement interesting color handling functions for
-use in stylesheets and I wanted the same thing for use in [Clay](http://fvisser.nl/clay/) (also for
-[Bentonite](https://github.com/ixmatus/bentonite)).
-
-## Colour Module
-
-There is some overlap with the Haskell Colour Module that already exists; however, this library is filling a couple of
-needs the other doesn't satisfy.
-
-## Supported Algorithms
-
-- sRGB <-> CIE XYZ
-- CIE XYZ <-> CIE L\*ab
-- CIE L\*ab <-> CIE L\*Ch
-
-## Supported Functions
-
-- Color interpolation
-- Tinting / Darkening
-- Lightness
-- Hue
-- Chroma/Saturation
-
-All of these functions operate on color within the CIE L\*Ch representation. The percentage values may range between
--100 and 100.
-
-[General Color Formulas, Data, and Algorithms](http://www.brucelindbloom.com/index.html?Info.html)
-
-[CIE Conversion Mathematics](http://rip94550.wordpress.com/2011/07/04/color-cielab-and-tristimulus-xyz/)
-
-[Conversion Algorithm Sources](http://www.easyrgb.com/index.php?X=MATH&H=01)
-
-[Good list of useful color manipulation](https://github.com/mikeemoo/ColorJizz-PHP/blob/master/src/MischiefCollective/ColorJizz/ColorJizz.php)
diff --git a/README.org b/README.org
new file mode 100644
--- /dev/null
+++ b/README.org
@@ -0,0 +1,36 @@
+* Welcome!
+  `prizm` is a Haskell library for computing with colors. Specifically
+  providing functions for transforming between different color spaces,
+  interpolating colors and adjusting the tint, shade, hue, or
+  lightness or a color.
+
+  My inspiration for writing this was Sass and Bourbon, both implement
+  interesting functions for computing with colors for use in
+  stylesheets and I wanted the same thing for use in [[http://fvisser.nl/clay/][Clay]].
+
+** Colour Module
+   There is some overlap with the Haskell Colour Module that already
+   exists; however, this library is filling a couple of needs the
+   other doesn't satisfy. Primarily transformations and color
+   mutations in the CIE L*Ch space.
+
+** Supported Algorithms
+   - sRGB <-> CIE XYZ
+   - CIE XYZ <-> CIE L\*ab
+   - CIE L\*ab <-> CIE L\*Ch
+
+** Supported Functions
+   - Color interpolation
+   - Tinting / Darkening
+   - Lightness
+   - Hue
+   - Chroma/Saturation
+
+   All of these functions operate on color within the CIE L\*Ch
+   representation. The percentage values may range between -100
+   and 100.
+
+[[http://www.brucelindbloom.com/index.html?Info.html][General Color Formulas, Data, and Algorithms]]
+[[http://rip94550.wordpress.com/2011/07/04/color-cielab-and-tristimulus-xyz/][CIE Conversion Mathematics]]
+[[http://www.easyrgb.com/index.php?X=MATH&H=01][Conversion Algorithm Sources]]
+[[https://github.com/mikeemoo/ColorJizz-PHP/blob/master/src/MischiefCollective/ColorJizz/ColorJizz.php][Good list of useful color manipulation formulas]]
diff --git a/prizm.cabal b/prizm.cabal
--- a/prizm.cabal
+++ b/prizm.cabal
@@ -1,29 +1,73 @@
-Name:                prizm
-Version:             0.3.1.0
-Synopsis:            A haskell library for computing with colors
+name:                prizm
+version:             0.3.1.1
+synopsis:            Compute with colors and differenct color spaces
+homepage:            https://github.com/ixmatus/prizm
+license:             BSD3
+license-file:        LICENSE
+author:              Parnell Springmeyer
+maintainer:          parnell@ixmat.us
+copyright:           (c) 2013 Parnell Springmeyer
+category:            Graphics
+build-type:          Simple
+stability:           stable
+bug-reports:         https://github.com/ixmatus/prizm/issues
+package-url:         http://hackage.haskell.org/package/prizm
+tested-with:         GHC == 7.6.3
+cabal-version:       >=1.14.0
 
-Description:         Prizm is a library for converting between
-                     different color representations and mutating
-                     colors (interpolation, lightness, hue, chroma,
-                     tint/shade).
 
-Homepage:            https://github.com/ixmatus/prizm
-License:             BSD3
-License-file:        LICENSE
-Author:              Parnell Springmeyer
-Maintainer:          ixmatus@gmail.com
-Copyright:           (c) 2013 Parnell Springmeyer
-Category:            Graphics
-Build-type:          Simple
-Stability:           alpha
-Bug-reports:         https://github.com/ixmatus/prizm/issues
-Package-url:         http://hackage.haskell.org/package/prizm
-Tested-with:         GHC == 7.4.2
-Cabal-version:       >=1.14.0
+description:
+  `prizm` is a Haskell library for computing with colors. Specifically
+  providing functions for transforming between different color spaces,
+  interpolating colors and adjusting the tint, shade, hue, or
+  lightness or a color.
+  .
+  My inspiration for writing this was Sass and Bourbon, both implement
+  interesting functions for computing with colors for use in
+  stylesheets and I wanted the same thing for use in <http://fvisser.nl/clay/ Clay>.
+  .
+  /Colour Module/
+  .
+  There is some overlap with the Haskell Colour Module that already
+  exists; however, this library is filling a couple of needs the
+  other doesn't satisfy. Primarily transformations and color
+  mutations in the CIE L*Ch space.
+  .
+  /Supported Algorithms & Functions/
+  .
+  All of these functions operate on color within the CIE L\*Ch
+  representation. The percentage values may range between -100
+  and 100.
+  .
+  * sRGB <-> CIE XYZ
+  .
+  * CIE XYZ <-> CIE L\*ab
+  .
+  * CIE L\*ab <-> CIE L\*Ch
+  .
+  * Color interpolation
+  .
+  * Tinting / Darkening
+  .
+  * Lightness
+  .
+  * Hue
+  .
+  * Chroma/Saturation
+  .
+  /Formulas, Resources, and Links/
+  .
+  * <http://www.brucelindbloom.com/index.html?Info.html General Color Formulas, Data, and Algorithms>
+  .
+  * <http://rip94550.wordpress.com/2011/07/04/color-cielab-and-tristimulus-xyz/ CIE Conversion Mathematics>
+  .
+  * <http://www.easyrgb.com/index.php?X=MATH&H=01 Conversion Algorithm Sources>
+  .
+  * <https://github.com/mikeemoo/ColorJizz-PHP/blob/master/src/MischiefCollective/ColorJizz/ColorJizz.php Good list of useful color manipulation formulas>
 
 extra-source-files:
     LICENSE
-    README.md
+    README.org
     CHANGES
 
 source-repository head
@@ -46,7 +90,7 @@
     Data.Prizm.Color.Matrices.XYZ
   
   ghc-options: -Wall
-  
+
   build-depends: base >= 4.5 && < 5,
                  text >= 0.11.2.3
 
@@ -54,7 +98,10 @@
   type:           exitcode-stdio-1.0
   hs-source-dirs: tests
   main-is:        QC.hs
-  other-modules:  QC.SRGB
+  default-language: Haskell2010
+  other-modules:
+    QC.SRGB
+    QC.CIE
 
   ghc-options:
     -Wall -threaded -rtsopts
diff --git a/src/Data/Prizm/Color.hs b/src/Data/Prizm/Color.hs
--- a/src/Data/Prizm/Color.hs
+++ b/src/Data/Prizm/Color.hs
@@ -1,25 +1,67 @@
-module Data.Prizm.Color (
-  (<|>)
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.Prizm.Color
+-- Copyright   :  (C) 2013 Parnell Springmeyer
+-- License     :  BSD3
+-- Maintainer  :  Parnell Springmeyer <parnell@ixmat.us>
+-- Stability   :  stable
+--
+-- 'Data.Prizm.Color' provides functions for blending colors,
+-- convenience blending ('tint' and 'shade'), and adjusting the 'hue',
+-- 'lightness', or 'chroma' of a given color.
+--
+-- These functions require your color to be represented in @CIE
+-- L*Ch@. The reason for this is because the @L*CH@ color space
+-- represents colors closest to how the human eye sees them. Blending
+-- and transforming a color in @L*Ch@ maintains the brightness of the
+-- colors more accurately. Here is a link to a blog post by someone
+-- detailing the differences and documenting them well:
+-- <http://www.stuartdenman.com/improved-color-blending/ Improved Color Blending>.
+--
+-- NOTE: the transformations between color spaces are intensive, if
+-- you have a HEX or RGB color it first needs to be transformed to the
+-- 'CIEXYZ' color space, then the 'CIELAB' space, and finally to
+-- 'CIELCH'.
+--
+-- I may at some point try to generalize the function's types but I
+-- wanted to first support 'CIELCH' as the transformation format.
+----------------------------------------------------------------------------
+module Data.Prizm.Color
+(
+-- * Blending
+  interpolate
+, (<|>)
 , shade
 , tint
+-- * Lightness, hue, and chroma
 , lightness
 , chroma
 , hue
-, interpolate
+-- * Types
+, module Data.Prizm.Types
 ) where
 
-import Control.Applicative hiding ((<|>))
-
-import Data.Prizm.Types
-
-pct :: Integer -> Double
-pct = (/100) . fromIntegral . (max (-100)) . (min 100)
+import           Control.Applicative hiding ((<|>))
+import           Data.Prizm.Types
 
-pctClamp :: Integer -> Integer
-pctClamp i = max (min i 100) 0
+------------------------------------------------------------------------------
+-- Blending
+------------------------------------------------------------------------------
 
-clamp :: Double -> Double -> Double
-clamp i clmp = max (min i clmp) 0.0
+-- | Interpolate two colors with a weight.
+--
+-- Weight is applied left to right, so if a weight of 25% is supplied,
+-- then the color on the left will be multiplied by 25% and the second
+-- color will be multiplied by 75%.
+--
+-- @CIE L*Ch@ is used because the interpolation between the colors is
+-- more accurate than 'CIELAB', 'CIEXYZ', and S'RGB' color spaces.
+interpolate :: Percent -> (CIELCH Double, CIELCH Double) -> CIELCH Double
+interpolate w (a,b) =
+    let w' = (pct (pctClamp w))
+        (CIELCH l c h) = (-) <$> b <*> a
+        a' = (*w') <$> (CIELCH l c (shortestPath h))
+    in (+) <$> a' <*> a
 
 -- | Blend two colors using an interpolation value of 50%.
 (<|>) :: CIELCH Double -> CIELCH Double -> CIELCH Double
@@ -33,36 +75,39 @@
 tint :: CIELCH Double -> Percent -> CIELCH Double
 tint c w = interpolate (pctClamp w) (c, CIELCH 100.0 0.0 360.0)
 
--- | Darken a color.
+------------------------------------------------------------------------------
+-- Lightness, hue, and chroma
+------------------------------------------------------------------------------
+
+-- | Adjust the lightness / darkness of a color.
 lightness :: CIELCH Double -> Percent -> CIELCH Double
 lightness (CIELCH l c h) w = (CIELCH (clamp (l + (100*(pct (pctClamp w)))) 100.0) c h)
 
--- | Change the hue of a color.
+-- | Adjust the hue of a color.
 hue :: CIELCH Double -> Percent -> CIELCH Double
 hue (CIELCH l c h) w = (CIELCH l c (clamp (h + (360*(pct (pctClamp w)))) 360.0))
 
--- | Change the saturation/chroma of a color. A maximum chroma value
--- of 120 is assumed here, anything more is generally considered out
--- of gamut.
+-- | Adjust the saturation/chroma of a color.
+--
+-- A maximum chroma value of 120 is assumed here, anything more is
+-- generally considered out of gamut.
 chroma :: CIELCH Double -> Percent -> CIELCH Double
 chroma (CIELCH l c h) w = (CIELCH l (clamp (c + (120*(pct (pctClamp w)))) 120.0) h)
 
--- | Interpolate two colors
--- 
--- Weight is applied left to right, so if a weight of 25% is supplied,
--- then the color on the left will be multiplied by 25% and the second
--- color will be multiplied by 75%.
--- 
--- CIE L*Ch is used because the interpolation between the colors is
--- more accurate than L*ab, XYZ, and sRGB color spaces.
-interpolate :: Percent -> (CIELCH Double, CIELCH Double) -> CIELCH Double
-interpolate w (a,b) =
-    let w' = (pct (pctClamp w))
-        (CIELCH l c h) = (-) <$> b <*> a
-        a' = (*w') <$> (CIELCH l c (shortestPath h))
-    in (+) <$> a' <*> a
+------------------------------------------------------------------------------
+-- Utility Functions
+------------------------------------------------------------------------------
 
 shortestPath :: Double -> Double
 shortestPath h | h > 180    = h - 360
                | h < (-180) = h + 360
                | otherwise  = h
+
+pct :: Integer -> Double
+pct = (/100) . fromIntegral . (max (-100)) . (min 100)
+
+pctClamp :: Integer -> Integer
+pctClamp i = max (min i 100) 0
+
+clamp :: Double -> Double -> Double
+clamp i clmp = max (min i clmp) 0.0
diff --git a/src/Data/Prizm/Color/CIE.hs b/src/Data/Prizm/Color/CIE.hs
--- a/src/Data/Prizm/Color/CIE.hs
+++ b/src/Data/Prizm/Color/CIE.hs
@@ -1,3 +1,13 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.Prizm.Color.CIE
+-- Copyright   :  (C) 2013 Parnell Springmeyer
+-- License     :  BSD3
+-- Maintainer  :  Parnell Springmeyer <parnell@ixmat.us>
+-- Stability   :  stable
+--
+-- Some basic utility functions for the CIE transformations.
+----------------------------------------------------------------------------
 module Data.Prizm.Color.CIE
 (
   v1
@@ -6,16 +16,17 @@
 , transformXYZ
 ) where
 
--- | exact rational of the "0.008856" value.
+-- | Exact rational of the "0.008856" value.
 v1 :: Double
 v1 = (6/29) ** 3
 
--- | exact rational of the "7.787" value.
+-- | Exact rational of the "7.787" value.
 v2 :: Double
 v2 = 1/3 * ((29/6) ** 2)
 
 -- 2deg observer, d65 illuminant
 -- [x,y,z]
+-- | Reference white, 2deg observer, d65 illuminant.
 refWhite :: [Double]
 refWhite = [95.047, 100.000, 108.883]
 
diff --git a/src/Data/Prizm/Color/CIE/LAB.hs b/src/Data/Prizm/Color/CIE/LAB.hs
--- a/src/Data/Prizm/Color/CIE/LAB.hs
+++ b/src/Data/Prizm/Color/CIE/LAB.hs
@@ -1,40 +1,64 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.Prizm.Color.CIE.LAB
+-- Copyright   :  (C) 2013 Parnell Springmeyer
+-- License     :  BSD3
+-- Maintainer  :  Parnell Springmeyer <parnell@ixmat.us>
+-- Stability   :  stable
+--
+-- Transformation functions and convenience functions, some imported
+-- from the other modules to ease conversion between representations.
+----------------------------------------------------------------------------
 module Data.Prizm.Color.CIE.LAB
 (
-  toLCH
-, toXYZ
-, toRGB
+-- * Transform to
+-- ** RGB or Hex
+  toRGB
 , toHex
-, fromXYZ
+-- ** CIE LCH or XYZ
+, toLCH
+, toXYZ
+
+-- * Transform from
+-- ** RGB or Hex
+
 , fromRGB
 , fromHex
+
+-- ** CIE XYZ or LCH
+, fromXYZ
 , fromLCH
 ) where
 
-import Control.Applicative
+import           Control.Applicative
 
-import Data.Prizm.Types
-import Data.Prizm.Color.CIE             (refWhite, transformXYZ)
+import           Data.Prizm.Color.CIE     (refWhite, transformXYZ)
+import           Data.Prizm.Types
 
-import qualified Data.Prizm.Color.SRGB      as S
-import qualified Data.Prizm.Color.CIE.XYZ   as X
-import {-# SOURCE #-} qualified Data.Prizm.Color.CIE.LCH   as LC
+import {-# SOURCE #-} qualified Data.Prizm.Color.CIE.LCH as LC
+import qualified Data.Prizm.Color.CIE.XYZ as X
+import qualified Data.Prizm.Color.SRGB    as S
 
-transformLCH :: Double -> Double
-transformLCH v | v > 0      = (v / pi) * 180
-               | otherwise  = 360 - ((abs v) / pi) * 180
+------------------------------------------------------------------------------
+-- Transform to
+------------------------------------------------------------------------------
 
--- | @toLCH@ convert a LAB color to the LCH representation.
+-- | Convenience function to convert LAB to RGB.
+toRGB :: CIELAB Double -> RGB Integer
+toRGB = X.toRGB . toXYZ
+
+-- | Convenience function to convert LAB to HEX.
+toHex :: CIELAB Double -> Hex
+toHex = X.toHex . toXYZ
+
+-- | Convert a LAB color to the LCH representation.
 toLCH :: CIELAB Double -> CIELCH Double
 toLCH (CIELAB l a b) =
     let h = transformLCH (atan2 b a)
-        c = sqrt ((a^2) + (b^2))
+        c = sqrt ((a^(2 :: Int)) + (b^(2 :: Int)))
     in CIELCH l c h
 
--- | @fromLCH@ convert a LCH color to the LAB representation.
-fromLCH :: CIELCH Double -> CIELAB Double
-fromLCH = LC.toLAB
-
--- | @toXYZ@ convert a LAB color to the XYZ representation.
+-- | Convert a LAB color to the XYZ representation.
 toXYZ :: CIELAB Double -> CIEXYZ Double
 toXYZ (CIELAB l a b) =
     let y = (l + 16) / 116
@@ -43,22 +67,26 @@
         [nx,ny,nz] = getZipList $ ((*) <$> ZipList ((transformXYZ) <$> [x,y,z])) <*> ZipList refWhite
     in CIEXYZ nx ny nz
 
--- | @fromXYZ@ convert an XYZ color straight to LAB.
-fromXYZ :: CIEXYZ Double -> CIELAB Double
-fromXYZ = X.toLAB
-
--- | @toRGB@ convenience function for converting straight to RGB.
-toRGB :: CIELAB Double -> RGB Integer
-toRGB = X.toRGB . toXYZ
+------------------------------------------------------------------------------
+-- Transform from
+------------------------------------------------------------------------------
 
--- | @fromRGB@ convenience function for converting to LAB from RGB.
+-- | Convenience function to convert RGB to LAB.
 fromRGB :: RGB Integer -> CIELAB Double
 fromRGB = X.toLAB . S.toXYZ
 
--- | @toHex@ convenience function for converting straight to HEX.
-toHex :: CIELAB Double -> Hex
-toHex = X.toHex . toXYZ
-
--- | @fromHex@ convenience function for converting to LAB from HEX.
+-- | Convenience function to convert HEX to LAB.
 fromHex :: Hex -> CIELAB Double
 fromHex = X.toLAB . X.fromHex
+
+-- | Convert an LCH color to the LAB representation.
+fromLCH :: CIELCH Double -> CIELAB Double
+fromLCH = LC.toLAB
+
+-- | Convert an XYZ color to LAB.
+fromXYZ :: CIEXYZ Double -> CIELAB Double
+fromXYZ = X.toLAB
+
+transformLCH :: Double -> Double
+transformLCH v | v > 0      = (v / pi) * 180
+               | otherwise  = 360 - ((abs v) / pi) * 180
diff --git a/src/Data/Prizm/Color/CIE/LCH.hs b/src/Data/Prizm/Color/CIE/LCH.hs
--- a/src/Data/Prizm/Color/CIE/LCH.hs
+++ b/src/Data/Prizm/Color/CIE/LCH.hs
@@ -1,48 +1,79 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.Prizm.Color.CIE.LCH
+-- Copyright   :  (C) 2013 Parnell Springmeyer
+-- License     :  BSD3
+-- Maintainer  :  Parnell Springmeyer <parnell@ixmat.us>
+-- Stability   :  stable
+--
+-- Transformation functions and convenience functions, some imported
+-- from the other modules to ease conversion between representations.
+----------------------------------------------------------------------------
 module Data.Prizm.Color.CIE.LCH
 (
+-- * Transform to
+-- ** RGB or Hex
+
   toRGB
+, toHex
+
+-- ** CIE LAB or XYZ
 , toLAB
 , toXYZ
-, toHex
+
+-- * Transform from
+-- ** RGB or Hex
 , fromRGB
 , fromHex
+
+-- ** CIE LAB or XYZ
 , fromLAB
 , fromXYZ
 ) where
 
-import Data.Prizm.Types
+import           Data.Prizm.Types
 
-import qualified Data.Prizm.Color.CIE.LAB as LB
+import {-# SOURCE #-} qualified Data.Prizm.Color.CIE.LAB as LB
 import qualified Data.Prizm.Color.CIE.XYZ as X
 
--- | @toLAB@ convert an LCH color to a LAB representation.
+------------------------------------------------------------------------------
+-- Transform to
+------------------------------------------------------------------------------
+
+-- | Convert from LCH to RGB.
+toRGB :: CIELCH Double -> RGB Integer
+toRGB = X.toRGB . toXYZ
+
+-- | Convert from LCH to Hex.
+toHex :: CIELCH Double -> Hex
+toHex = LB.toHex . toLAB
+
+-- | Convert an LCH color to LAB.
 toLAB :: CIELCH Double -> CIELAB Double
 toLAB (CIELCH l c h) =
     let v = h * pi / 180
     in CIELAB l ((cos v)*c) ((sin v)*c)
 
--- | @fromLAB@ convenience function for converting from LAB to LCH.
-fromLAB :: CIELAB Double -> CIELCH Double
-fromLAB = LB.toLCH
-
--- | @toXYZ@ convert from LCH to XYZ.
+-- | Convert from LCH to XYZ.
 toXYZ :: CIELCH Double -> CIEXYZ Double
 toXYZ = LB.toXYZ . toLAB
 
--- | @fromXYZ@ convert from XYZ to LCH.
-fromXYZ :: CIEXYZ Double -> CIELCH Double
-fromXYZ = X.toLCH
-
--- | @toRGB@ convert from LCH to RGB.
-toRGB :: CIELCH Double -> RGB Integer
-toRGB = X.toRGB . toXYZ
+------------------------------------------------------------------------------
+-- Transform from
+------------------------------------------------------------------------------
 
--- | @fromRGB@ convert from RGB to LCH.
+-- | Convenience function to convert from RGB to LCH.
 fromRGB :: RGB Integer -> CIELCH Double
 fromRGB = fromLAB . LB.fromRGB
 
-toHex :: CIELCH Double -> Hex
-toHex = LB.toHex . toLAB
-
+-- | Convenience function to convert from Hex to LCH.
 fromHex :: Hex -> CIELCH Double
 fromHex = LB.toLCH . LB.fromHex
+
+-- | Convenience function to convert from LAB to LCH.
+fromLAB :: CIELAB Double -> CIELCH Double
+fromLAB = LB.toLCH
+
+-- | Convert from XYZ to LCH.
+fromXYZ :: CIEXYZ Double -> CIELCH Double
+fromXYZ = X.toLCH
diff --git a/src/Data/Prizm/Color/CIE/XYZ.hs b/src/Data/Prizm/Color/CIE/XYZ.hs
--- a/src/Data/Prizm/Color/CIE/XYZ.hs
+++ b/src/Data/Prizm/Color/CIE/XYZ.hs
@@ -1,67 +1,89 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.Prizm.Color.CIE.XYZ
+-- Copyright   :  (C) 2013 Parnell Springmeyer
+-- License     :  BSD3
+-- Maintainer  :  Parnell Springmeyer <parnell@ixmat.us>
+-- Stability   :  stable
+--
+-- Transformation functions and convenience functions, some imported
+-- from the other modules to ease conversion between representations.
+----------------------------------------------------------------------------
 module Data.Prizm.Color.CIE.XYZ
 (
+-- * Transform to
+-- ** RGB or Hex
   toRGB
 , toRGBMatrix
+, toHex
+
+-- ** CIE LAB or LCH
 , toLAB
 , toLCH
-, toHex
+
+-- * Transform from
+-- ** RGB or Hex
 , fromRGB
 , fromHex
+
+-- ** CIE LAB or LCH
 , fromLAB
 , fromLCH
 ) where
 
-import Control.Applicative
+import           Control.Applicative
 
-import Data.Prizm.Types
+import           Data.Prizm.Types
 
-import Data.Prizm.Color.Transform
-import Data.Prizm.Color.Matrices.XYZ
-import Data.Prizm.Color.CIE                 (v1, v2, refWhite)
+import           Data.Prizm.Color.CIE          (refWhite, v1, v2)
+import           Data.Prizm.Color.Matrices.XYZ
+import           Data.Prizm.Color.Transform
 
-import qualified Data.Prizm.Color.SRGB      as S
-import {-# SOURCE #-} qualified Data.Prizm.Color.CIE.LAB   as LB
-import {-# SOURCE #-} qualified Data.Prizm.Color.CIE.LCH   as LC
+import {-# SOURCE #-} qualified Data.Prizm.Color.CIE.LAB      as LB
+import {-# SOURCE #-} qualified Data.Prizm.Color.CIE.LCH      as LC
+import qualified Data.Prizm.Color.SRGB         as S
 
+------------------------------------------------------------------------------
+-- Utilities
+------------------------------------------------------------------------------
 
--- | @transformRGB@ transform an XYZ integer to be computed against
--- the xyzToRGB matrix.
+-- | Transform an XYZ integer to be computed against the xyzToRGB
+-- matrix.
 transformRGB :: Double -> Integer
 transformRGB v | v > 0.0031308 = min (round ((1.055 * (v ** (1 / 2.4)) - 0.055) * 255)) 255
                | otherwise     = min (round ((12.92 * v) * 255)) 255
 
+-- | Transform an LAB integer.
 transformLAB :: Double -> Double
 transformLAB v | v > v1    = v ** (1/3)
                | otherwise = (v2 * v) + (16 / 116)
 
--- | @toRGB@ convert a CIE color to an SRGB color.
--- 
+------------------------------------------------------------------------------
+-- Transform to
+------------------------------------------------------------------------------
+
+-- | Convert a CIE color to an SRGB color.
+--
 -- This function uses the default d65 illuminant matrix.
 toRGB :: CIEXYZ Double -> RGB Integer
 toRGB = (toRGBMatrix d65SRGB)
 
--- | @toRGBMatrix@ convert an XYZ color to an SRGB color using a
--- provided matrix.
+-- | Convert an XYZ color to an SRGB color.
+--
+-- 'XYZtoRGB' is the pre-calculated illuminant matrix, it is
+-- preferable to use 'toRG' as it uses the most "common" one.
 toRGBMatrix :: XYZtoRGB -> CIEXYZ Double -> RGB Integer
 toRGBMatrix (XYZtoRGB m) (CIEXYZ x y z) =
     let t = ZipList ((/100) <$> [x,y,z])
         [r,g,b] = (transformRGB) <$> ((zipTransform t) <$> m)
     in (S.clamp) <$> RGB r g b
 
--- | @fromRGB@ convenience function for converting to XYZ from RGB.
-fromRGB :: RGB Integer -> CIEXYZ Double
-fromRGB = S.toXYZ
-
--- | @toHex@ convenience function for converting XYZ straight to HEX.
+-- | Convenience function to convert XYZ to HEX.
 toHex :: CIEXYZ Double -> Hex
 toHex = S.toHex . toRGB
 
--- | @fromHex@ convenience function for converting to XYZ from HEX.
-fromHex :: Hex -> CIEXYZ Double
-fromHex = S.toXYZ . S.fromHex
-
--- | @toLAB@ convert an XYZ color to a LAB color.
--- 
+-- | Convert an XYZ color to a LAB color.
+--
 -- This function uses the default reference white (2deg observer, d65
 -- illuminant).
 toLAB :: CIEXYZ Double -> CIELAB Double
@@ -73,13 +95,26 @@
         b = 200 * (ty - tz)
     in CIELAB l a b
 
--- | @fromLAB@ convenience function for converting to XYZ from LAB.
-fromLAB :: CIELAB Double -> CIEXYZ Double
-fromLAB = LB.toXYZ
-
--- | @toLCH@ convenience function for converting XYZ straight to LAB.
+-- | Convenience function to convert XYZ to LAB.
 toLCH :: CIEXYZ Double -> CIELCH Double
 toLCH = LB.toLCH . toLAB
 
+------------------------------------------------------------------------------
+-- Transform from
+------------------------------------------------------------------------------
+
+-- | Convenience function to convert RGB to XYZ.
+fromRGB :: RGB Integer -> CIEXYZ Double
+fromRGB = S.toXYZ
+
+-- | Convenience function to convert HEX to XYZ.
+fromHex :: Hex -> CIEXYZ Double
+fromHex = S.toXYZ . S.fromHex
+
+-- | Convenience function to convert LAB to XYZ.
+fromLAB :: CIELAB Double -> CIEXYZ Double
+fromLAB = LB.toXYZ
+
+-- | Convenience function to convert LCH to XYZ.
 fromLCH :: CIELCH Double -> CIEXYZ Double
 fromLCH = LC.toXYZ
diff --git a/src/Data/Prizm/Color/SRGB.hs b/src/Data/Prizm/Color/SRGB.hs
--- a/src/Data/Prizm/Color/SRGB.hs
+++ b/src/Data/Prizm/Color/SRGB.hs
@@ -1,26 +1,44 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.Prizm.Color.SRGB
+-- Copyright   :  (C) 2013 Parnell Springmeyer
+-- License     :  BSD3
+-- Maintainer  :  Parnell Springmeyer <parnell@ixmat.us>
+-- Stability   :  stable
+--
+-- Transformation functions and convenience functions to do the base
+-- conversion between S'RGB' and 'CIEXYZ'.
+----------------------------------------------------------------------------
 module Data.Prizm.Color.SRGB
 (
+-- * Convert to CIEXYZ
   toXYZ
 , toXYZMatrix
+
+-- * Convert to Hex
 , toHex
 , fromHex
 , clamp
 ) where
 
-import Numeric (showHex)
+import           Numeric                       (showHex)
 
-import Data.Monoid
-import Data.Prizm.Types
-import Data.Prizm.Color.Transform
-import Data.Prizm.Color.Matrices.RGB
+import           Data.Monoid
+import           Data.Prizm.Color.Matrices.RGB
+import           Data.Prizm.Color.Transform
+import           Data.Prizm.Types
 
-import Data.String
-import qualified Data.Text as T
-import Data.Text.Read as R
+import           Data.String
+import qualified Data.Text                     as T
+import           Data.Text.Read                as R
 
-import Control.Applicative
+import           Control.Applicative
 
--- | @rgbTransform@ transform an RGB integer to be computed against
+------------------------------------------------------------------------------
+-- Utilities
+------------------------------------------------------------------------------
+
+-- | Transform an RGB integer to be computed against
 -- a matrix.
 transform :: Integer -> Double
 transform v | dv > 0.04045 = (((dv + 0.055) / ap) ** 2.4) * 100
@@ -28,13 +46,23 @@
     where dv = fromIntegral v / 255
           ap = 1.0 + 0.055
 
--- | @toHex@ convert an sRGB value to hexadecimal.
-toHex :: RGB Integer -> Hex
-toHex = showRGB
+-- | Clamp an integer with an upper-bound of 255 (the maximum RGB
+-- value).
+clamp :: Integer -> Integer
+clamp i = max (min i 255) 0
 
-fromHex :: Hex -> RGB Integer
-fromHex = parse . fromString
+-- All credit for the below three functions go to the HSColour module.
 
+-- | Show a colour in hexadecimal form, e.g. \"#00aaff\"
+showRGB :: RGB Integer -> Hex
+showRGB c =
+  (("#"++) . showHex2 r' . showHex2 g' . showHex2 b') ""
+ where
+  RGB r' g' b' = c
+  showHex2 x | x <= 0xf = ("0"++) . showHex x
+             | otherwise = showHex x
+
+-- | Parse a 'Hex' into an 'RGB' type.
 parse :: T.Text -> RGB Integer
 parse t =
   case T.uncons t of
@@ -52,27 +80,38 @@
     isHex a = (a >= 'a' && a <= 'f') || (a >= 'A' && a <= 'F') || (a >= '0' && a <= '9')
     err     = error "Invalid color string"
 
--- | @toXYZ@ convert an sRGB value to a CIE XYZ value.
+------------------------------------------------------------------------------
+-- Convert to XYZ
+------------------------------------------------------------------------------
+
+-- | Convert an S'RGB' value to a 'CIEXYZ' value.
 toXYZ :: RGB Integer -> CIEXYZ Double
 toXYZ = (toXYZMatrix d65SRGB)
 
+-- | Convert an S'RGB' value to a 'CIEXYZ' given a pre-calculated
+-- illuminant matrix.
+--
+-- It is recommended to use 'toXYZ' as it uses the most common
+-- illuminant matrix.
 toXYZMatrix :: RGBtoXYZ -> RGB Integer -> CIEXYZ Double
 toXYZMatrix (RGBtoXYZ m) (RGB r g b) =
     let t = ZipList (transform <$> (clamp <$> [r,g,b]))
         [x,y,z] = (roundN 3) <$> ((zipTransform t) <$> m)
     in CIEXYZ x y z
 
-clamp :: Integer -> Integer
-clamp i = max (min i 255) 0
+------------------------------------------------------------------------------
+-- Convert to Hex
+------------------------------------------------------------------------------
 
-{- All credit for the below three functions go to the HSColour
-   module-}
+-- | Convert an S'RGB' value to 'Hex'.
+toHex :: RGB Integer -> Hex
+toHex = showRGB
 
--- |Show a colour in hexadecimal form, e.g. \"#00aaff\"
-showRGB :: RGB Integer -> Hex
-showRGB c =
-  (("#"++) . showHex2 r' . showHex2 g' . showHex2 b') ""
- where
-  RGB r' g' b' = c
-  showHex2 x | x <= 0xf = ("0"++) . showHex x
-             | otherwise = showHex x
+-- | Convert a 'Hex' to an S'RGB'.
+fromHex :: Hex -> RGB Integer
+fromHex = parse . fromString
+
+
+
+
+
diff --git a/src/Data/Prizm/Color/Transform.hs b/src/Data/Prizm/Color/Transform.hs
--- a/src/Data/Prizm/Color/Transform.hs
+++ b/src/Data/Prizm/Color/Transform.hs
@@ -2,13 +2,15 @@
 
 module Data.Prizm.Color.Transform where
 
-import Control.Applicative
+import           Control.Applicative
 
+-- | Round a number to the Nth place.
 roundN :: Integer -> Double -> Double
 roundN n num = (fromInteger $ round $ num * (10^n)) / (10.0^^n)
 
+-- | Truncate a number to the Nth place.
 truncateN :: Integer -> Double -> Double
-truncateN n num = (fromInteger $ truncate $ num * (10^n)) / (10.0^^n)
+truncateN = roundN
 
 zipTransform :: ZipList Double -> [Double] -> Double
 zipTransform tv m = sum $ getZipList $ (*) <$> ZipList m <*> tv
diff --git a/src/Data/Prizm/Types.hs b/src/Data/Prizm/Types.hs
--- a/src/Data/Prizm/Types.hs
+++ b/src/Data/Prizm/Types.hs
@@ -1,10 +1,14 @@
 module Data.Prizm.Types where
 
-import Control.Applicative
+import           Control.Applicative
 
+-- | Working space matrix to convert from sRGB to CIE XYZ
 newtype RGBtoXYZ = RGBtoXYZ [[Double]] deriving (Eq, Ord, Show)
+
+-- | Working space matrix to convert from CIE XYZ to sRGB
 newtype XYZtoRGB = XYZtoRGB [[Double]] deriving (Eq, Ord, Show)
 
+-- | Hex format color code, eg '#AB9D92'
 type Hex = String
 
 type Percent = Integer
@@ -22,6 +26,7 @@
     deriving (Eq, Ord, Show)
 
 -- | Functor instances
+
 instance Functor RGB where
     fmap f (RGB r g b) = (RGB (f r) (f g) (f b))
 
diff --git a/tests/QC/CIE.hs b/tests/QC/CIE.hs
new file mode 100644
--- /dev/null
+++ b/tests/QC/CIE.hs
@@ -0,0 +1,53 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
+module QC.CIE (tests) where
+
+import           Test.Framework                       (Test)
+import           Test.Framework.Providers.QuickCheck2 (testProperty)
+import           Test.QuickCheck
+
+import           Control.Applicative
+import           Control.Monad
+
+import           Data.Prizm.Color.CIE.LAB             as LB
+import           Data.Prizm.Color.CIE.LCH             as LC
+import           Data.Prizm.Color.CIE.XYZ             as X
+import           Data.Prizm.Color.Transform
+import           Data.Prizm.Types
+
+instance Arbitrary (CIEXYZ Double) where
+    arbitrary = liftM3 CIEXYZ (choose (0, 95.047)) (choose (0, 100.000)) (choose (0, 108.883))
+
+instance Arbitrary (CIELAB Double) where
+    arbitrary = liftM3 CIELAB (choose (0, 100)) (choose ((-129), 129)) (choose ((-129), 129))
+
+rN :: Double -> Double
+rN = roundN 11
+
+-- | This really needs applicatives here - I need to redefine the
+-- types so that I can fmap functions over the color values.
+--
+-- This QuickCheck test guarantees a lossless conversion between CIE
+-- XYZ and CIE L*a*b* at a precision of 11 decimal places.
+xyz2LAB :: CIEXYZ Double -> Bool
+xyz2LAB v =
+    let nv = rN <$> v
+    in (rN <$> LB.toXYZ(X.toLAB nv)) == nv
+
+lab2XYZ :: CIELAB Double -> Bool
+lab2XYZ v =
+    let nv = rN <$> v
+    in (rN <$> X.toLAB(LB.toXYZ nv)) == nv
+
+lab2LCH :: CIELAB Double -> Bool
+lab2LCH v =
+    let nv = rN <$> v
+    in (rN <$> LC.toLAB(LB.toLCH nv)) == nv
+
+tests :: [Test]
+tests = [
+    testProperty "CIE XYZ <-> CIE L*a*b*" xyz2LAB,
+    testProperty "CIE L*ab <-> CIE XYZ" lab2XYZ,
+    testProperty "CIE L*ab <-> CIE L*Ch" lab2LCH
+      ]
