diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,2 +1,8 @@
+New in version 2.3:
+
+- black exported by Data.Colour
+
+- CIELAB conversion functions
+
 New in version 2.2.1:
- - Additional Documenation 
+ - Additional Documenation
diff --git a/Data/Colour.hs b/Data/Colour.hs
--- a/Data/Colour.hs
+++ b/Data/Colour.hs
@@ -108,6 +108,7 @@
 -- *Colour type
   Colour
  ,colourConvert
+ ,black
 
  ,AlphaColour
  ,opaque, withOpacity
diff --git a/Data/Colour/CIE.hs b/Data/Colour/CIE.hs
--- a/Data/Colour/CIE.hs
+++ b/Data/Colour/CIE.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (c) 2008
+Copyright (c) 2008, 2009
 Russell O'Connor
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -24,7 +24,8 @@
 -- Illumination (CIE).
 module Data.Colour.CIE
  (Colour
- ,cieXYZ, toCIEXYZ, luminance
+ ,cieXYZ, cieXYZView, luminance
+ ,toCIEXYZ -- depricated
 
  ,Chromaticity
  ,mkChromaticity, chromaCoords
@@ -32,7 +33,7 @@
  ,chromaConvert
  ,chromaColour
 
- --,lightness, cieLab, cieLuv
+ ,lightness, cieLABView, cieLAB --cieLuv
  )
 where
 
@@ -51,15 +52,18 @@
   [r,g,b] = mult matrix [x,y,z]
   matrix = map (map fromRational) xyz2rgb709
 
--- |Return the XYZ colour coordinates for the 2&#176; standard
+-- |Returns the XYZ colour coordinates for the 2&#176; standard
 -- (colourimetric) observer.
-toCIEXYZ :: (Fractional a) => Colour a -> (a,a,a)
-toCIEXYZ c = (x,y,z)
+cieXYZView :: (Fractional a) => Colour a -> (a,a,a)
+cieXYZView c = (x,y,z)
  where
   RGB r g b = toRGB c
   [x,y,z] = mult matrix [r,g,b]
   matrix = map (map fromRational) rgb7092xyz
 
+{-# DEPRECATED toCIEXYZ "`toCIEXYZ' has been renamed `cieXYZView'" #-}
+toCIEXYZ x = cieXYZView x
+
 {- CIE luminance -}
 -- |Returns the Y colour coordinate (luminance) for the 2&#176; standard
 -- (colourimetric) observer.
@@ -86,28 +90,56 @@
   (ch_x, ch_y, ch_z) = chromaCoords ch
   s = y/ch_y
 
--- |Returns the lightness of a colour, which is a perceptually uniform
--- measure.
-lightness :: (Ord a, Floating a) => Colour a -> a
-lightness c | (6/29)^3 < y = 116*y**(1/3) - 16
-            | otherwise = (29/3)^3*y
+-- |Returns the lightness of a colour with respect to a given white point.
+-- Lightness is a perceptually uniform measure.
+lightness :: (Ord a, Floating a) => Chromaticity a -- ^White point
+                                 -> Colour a -> a
+lightness white_ch c | (6/29)^3 < y' = 116*y'**(1/3) - 16
+                     | otherwise = (29/3)^3*y'
  where
-  y = luminance c
+  white = chromaColour white_ch 1.0
+  y' = (luminance c/luminance white)
 
 -- |Returns the CIELAB coordinates of a colour, which is a
 -- perceptually uniform colour space.
+-- The first coordinate is 'lightness'.
 -- If you don't know what white point to use, use
 -- 'Data.Colour.CIE.Illuminant.d65'.
-cieLab :: (Ord a, Floating a) => Chromaticity a -- ^White point
+cieLABView :: (Ord a, Floating a) => Chromaticity a -- ^White point
                               -> Colour a -> (a,a,a)
-cieLab white_ch c = (lightness c, a, b)
+cieLABView white_ch c = (lightness white_ch c, a, b)
  where
   white = chromaColour white_ch 1.0
   (x,y,z) = toCIEXYZ c
   (xn,yn,zn) = toCIEXYZ white
-  a = 500*((x/xn)**(1/3) - (y/yn)**(1/3))
-  b = 200*((y/yn)**(1/3) - (z/zn)**(1/3))
+  (fx, fy, fz) = (f (x/xn), f (y/yn), f (z/zn))
+  a = 500*(fx - fy)
+  b = 200*(fy - fz)
+  f x | (6/29)^3 < x = x**(1/3)
+      | otherwise = 841/108*x + 4/29
 
+-- |Returns the colour for given CIELAB coordinates, which is a
+-- perceptually uniform colour space.
+-- If you don't know what white point to use, use
+-- 'Data.Colour.CIE.Illuminant.d65'.
+cieLAB :: (Ord a, Floating a) => Chromaticity a -- ^White point
+                              -> a              -- ^L* coordinate (lightness)
+                              -> a              -- ^a* coordinate
+                              -> a              -- ^b* coordinate
+                              -> Colour a
+cieLAB white_ch l a b = cieXYZ (xn*transform fx)
+                               (yn*transform fy)
+                               (zn*transform fz)
+ where
+  white = chromaColour white_ch 1.0
+  (xn,yn,zn) = toCIEXYZ white
+  fx = fy + a/500
+  fy = (l + 16)/116
+  fz = fy - b/200
+  delta = 6/29
+  transform fa | fa > delta = fa^3
+               | otherwise = (fa - 16/116)*3*delta^2
+
 -- |Returns the CIELUV coordinates of a colour, which is a
 -- perceptually uniform colour space.
 -- If you don't know what white point to use, use
@@ -119,7 +151,7 @@
   white = chromaColour white_ch 1.0
   (u', v') = u'v' c
   (un', vn') = u'v' white
-  l = lightness c
+  l = lightness white_ch c
 --------------------------------------------------------------------------
 {- not for export -}
 u'v' :: (Ord a, Floating a) => Colour a -> (a,a)
@@ -130,4 +162,3 @@
 rgb7092xyz = (rgb2xyz sRGBGamut)
 
 xyz2rgb709 = inverse rgb7092xyz
-
diff --git a/Data/Colour/Internal.hs b/Data/Colour/Internal.hs
--- a/Data/Colour/Internal.hs
+++ b/Data/Colour/Internal.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (c) 2008
+Copyright (c) 2008, 2009
 Russell O'Connor
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -48,8 +48,13 @@
 colourConvert (RGB r g b) =
   RGB (Chan.convert r) (Chan.convert g) (Chan.convert b)
 
+-- |'black' is the colourless colour.  It is the identity colour in
+-- additive colour spaces.
+black :: (Num a) => Colour a
+black = RGB Chan.empty Chan.empty Chan.empty
+
 instance (Num a) => Monoid (Colour a) where
-  mempty = RGB Chan.empty Chan.empty Chan.empty
+  mempty = black
   (RGB r1 g1 b1) `mappend` (RGB r2 g2 b2) =
     RGB (r1 `Chan.add` r2) (g1 `Chan.add` g2) (b1 `Chan.add` b2)
   mconcat l = RGB (Chan.sum lr) (Chan.sum lg) (Chan.sum lb)
diff --git a/Data/Colour/Names.hs b/Data/Colour/Names.hs
--- a/Data/Colour/Names.hs
+++ b/Data/Colour/Names.hs
@@ -1,5 +1,6 @@
+{-# OPTIONS_HADDOCK prune #-}
 {-
-Copyright (c) 2008
+Copyright (c) 2008, 2009
 Russell O'Connor
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -28,10 +29,162 @@
 -- 'readColourName' takes a string naming a colour (must be all lowercase)
 -- and returns the colour.
 -- Fails if the name is not recognized.
-module Data.Colour.Names where
+module Data.Colour.Names 
+ (
+  readColourName
+ ,aliceblue
+ ,antiquewhite
+ ,aqua
+ ,aquamarine
+ ,azure
+ ,beige
+ ,bisque
+ ,black
+ ,blanchedalmond
+ ,blue
+ ,blueviolet
+ ,brown
+ ,burlywood
+ ,cadetblue
+ ,chartreuse
+ ,chocolate
+ ,coral
+ ,cornflowerblue
+ ,cornsilk
+ ,crimson
+ ,cyan
+ ,darkblue
+ ,darkcyan
+ ,darkgoldenrod
+ ,darkgray
+ ,darkgreen
+ ,darkgrey
+ ,darkkhaki
+ ,darkmagenta
+ ,darkolivegreen
+ ,darkorange
+ ,darkorchid
+ ,darkred
+ ,darksalmon
+ ,darkseagreen
+ ,darkslateblue
+ ,darkslategray
+ ,darkslategrey
+ ,darkturquoise
+ ,darkviolet
+ ,deeppink
+ ,deepskyblue
+ ,dimgray
+ ,dimgrey
+ ,dodgerblue
+ ,firebrick
+ ,floralwhite
+ ,forestgreen
+ ,fuchsia
+ ,gainsboro
+ ,ghostwhite
+ ,gold
+ ,goldenrod
+ ,gray
+ ,grey
+ ,green
+ ,greenyellow
+ ,honeydew
+ ,hotpink
+ ,indianred
+ ,indigo
+ ,ivory
+ ,khaki
+ ,lavender
+ ,lavenderblush
+ ,lawngreen
+ ,lemonchiffon
+ ,lightblue
+ ,lightcoral
+ ,lightcyan
+ ,lightgoldenrodyellow
+ ,lightgray
+ ,lightgreen
+ ,lightgrey
+ ,lightpink
+ ,lightsalmon
+ ,lightseagreen
+ ,lightskyblue
+ ,lightslategray
+ ,lightslategrey
+ ,lightsteelblue
+ ,lightyellow
+ ,lime
+ ,limegreen
+ ,linen
+ ,magenta
+ ,maroon
+ ,mediumaquamarine
+ ,mediumblue
+ ,mediumorchid
+ ,mediumpurple
+ ,mediumseagreen
+ ,mediumslateblue
+ ,mediumspringgreen
+ ,mediumturquoise
+ ,mediumvioletred
+ ,midnightblue
+ ,mintcream
+ ,mistyrose
+ ,moccasin
+ ,navajowhite
+ ,navy
+ ,oldlace
+ ,olive
+ ,olivedrab
+ ,orange
+ ,orangered
+ ,orchid
+ ,palegoldenrod
+ ,palegreen
+ ,paleturquoise
+ ,palevioletred
+ ,papayawhip
+ ,peachpuff
+ ,peru
+ ,pink
+ ,plum
+ ,powderblue
+ ,purple
+ ,red
+ ,rosybrown
+ ,royalblue
+ ,saddlebrown
+ ,salmon
+ ,sandybrown
+ ,seagreen
+ ,seashell
+ ,sienna
+ ,silver
+ ,skyblue
+ ,slateblue
+ ,slategray
+ ,slategrey
+ ,snow
+ ,springgreen
+ ,steelblue
+ ,tan
+ ,teal
+ ,thistle
+ ,tomato
+ ,turquoise
+ ,violet
+ ,wheat
+ ,white
+ ,whitesmoke
+ ,yellow
+ ,yellowgreen
+ )
+where
 
 import Prelude hiding (tan)
 import Data.Colour.SRGB
+import Data.Colour (black)
 
 readColourName :: (Monad m, Ord a, Floating a) => String -> m (Colour a)
 readColourName "aliceblue" = return aliceblue
@@ -205,8 +358,7 @@
 bisque :: (Ord a, Floating a) => Colour a
 bisque = sRGB24 255 228 196
 
-black :: (Ord a, Floating a) => Colour a
-black = sRGB24 0 0 0
+-- black is reexported from Data.Colour
 
 blanchedalmond :: (Ord a, Floating a) => Colour a
 blanchedalmond = sRGB24 255 235 205
diff --git a/Data/Colour/RGB.hs b/Data/Colour/RGB.hs
--- a/Data/Colour/RGB.hs
+++ b/Data/Colour/RGB.hs
@@ -25,6 +25,7 @@
 import Data.List
 import Data.Colour.Matrix
 import Data.Colour.CIE.Chromaticity
+import Control.Applicative
 
 -- |An RGB triple for an unspecified colour space.
 data RGB a = RGB {channelRed :: !a
@@ -34,6 +35,10 @@
 
 instance Functor RGB where
  fmap f (RGB r g b) = RGB (f r) (f g) (f b)
+
+instance Applicative RGB where
+ pure c = RGB c c c
+ (RGB fr fg fb) <*> (RGB r g b) = RGB (fr r) (fg g) (fb b)
 
 -- |Uncurries a function expecting three r, g, b parameters.
 uncurryRGB :: (a -> a -> a -> b) -> RGB a -> b
diff --git a/Data/Colour/SRGB.hs b/Data/Colour/SRGB.hs
--- a/Data/Colour/SRGB.hs
+++ b/Data/Colour/SRGB.hs
@@ -1,5 +1,5 @@
 {-
-Copyright (c) 2008,2009
+Copyright (c) 2008
 Russell O'Connor
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -38,12 +38,6 @@
 import Data.Colour.Internal (quantize)
 import Data.Colour.SRGB.Linear
 import Data.Colour.RGBSpace hiding (transferFunction)
-
-{- a rewrite rule to think about adding.
-   Should I have some instance restrictions (like Word8/Word16 Float/Double)?
-# RULES "sRGBBounded" 
-  forall r g b. toSRGBBounded (sRGBBounded r g b) = RGB r g b #
--}
 
 {- Non-linear colour space -}
 {- the sRGB transfer function approximates a gamma of about 1/2.2 -}
diff --git a/Data/Colour/SRGB/Linear.hs b/Data/Colour/SRGB/Linear.hs
--- a/Data/Colour/SRGB/Linear.hs
+++ b/Data/Colour/SRGB/Linear.hs
@@ -1,5 +1,6 @@
+{-# OPTIONS_HADDOCK not-home #-}
 {-
-Copyright (c) 2008
+Copyright (c) 2008, 2009
 Russell O'Connor
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2008
+Copyright (c) 2008, 2009
 Russell O'Connor
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/Tests.hs b/Tests.hs
--- a/Tests.hs
+++ b/Tests.hs
@@ -35,6 +35,7 @@
 import Data.Colour.SRGB
 import Data.Colour.SRGB.Linear
 import Data.Colour.CIE
+import Data.Colour.CIE.Illuminant (d65)
 import Data.Colour.Names
 --import Data.Colour.HDTV as HDTV
 --import qualified Data.Colour.SDTV as SDTV
@@ -79,8 +80,7 @@
   coarbitrary ac = coarbitrary a . coarbitrary c
    where
     a = alphaChannel ac
-    c = ac `over` mempty
-    d = opaque c `asTypeOf` ac -- to help the type sytem
+    c = ac `over` black
 
 instance (Fractional a, Arbitrary a) =>
          Arbitrary (Chromaticity a) where
@@ -132,10 +132,10 @@
 prop_toFromXYZ :: RColour -> Bool
 prop_toFromXYZ c = (cieXYZ x y z) == c
  where
-  (x,y,z) = toCIEXYZ c
+  (x,y,z) = cieXYZView c
 
 prop_fromToXYZ :: Rational -> Rational -> Rational -> Bool
-prop_fromToXYZ x y z = toCIEXYZ (cieXYZ x y z) == (x,y,z)
+prop_fromToXYZ x y z = cieXYZView (cieXYZ x y z) == (x,y,z)
 
 -- Uses the fact that an Arbitrary colour is an sRGB24 colour.
 prop_toFromSRGB :: DColour -> Bool
@@ -144,6 +144,12 @@
 prop_fromToSRGB :: Word8 -> Word8 -> Word8 -> Bool
 prop_fromToSRGB r' g' b' = toSRGB24 (sRGB24 r' g' b') == RGB r' g' b'
 
+prop_toFromLAB :: Chromaticity Double -> DColour -> Bool
+prop_toFromLAB wp c = cc (cieLAB wp l a b) == cc c
+ where
+  (l,a,b) = cieLABView wp c
+  cc = toSRGB24
+
 {-
 prop_fromToY'CbCr709 :: Word8 -> Word8 -> Word8 -> Bool
 prop_fromToY'CbCr709 y' cb cr =
@@ -277,6 +283,7 @@
         ,("XYZ-from-to", test prop_fromToXYZ)
         ,("sRGB-to-from", test prop_toFromSRGB)
         ,("sRGB-from-to", test prop_fromToSRGB)
+        ,("cieLAB-to-from", test (prop_toFromLAB d65))
 --        ,("Y'CbCr-709-from-to", test prop_fromToY'CbCr709)
 --        ,("Y'CbCr-601-from-to", test prop_fromToY'CbCr601)
         ,("dissolve-id", test prop_disolveId)
diff --git a/colour.cabal b/colour.cabal
--- a/colour.cabal
+++ b/colour.cabal
@@ -1,10 +1,11 @@
 Name:                colour
-Version:             2.2.1
+Version:             2.3.0
 Cabal-Version:       >= 1.2
 License:             OtherLicense
 License-file:        LICENSE
 Author:              Russell O'Connor
 Maintainer:          Russell O'Connor <roconnor@theorem.ca>
+Homepage:            http://www.haskell.org/haskellwiki/Colour
 Build-Type:          Simple
 Category:            data, graphics
 Synopsis:            A model for human colour/color perception
@@ -17,7 +18,7 @@
 data-files:          README CHANGELOG
 
 Library
-  Build-Depends:     base
+  Build-Depends:     base >= 3 && < 5
   Exposed-Modules:   Data.Colour
                      Data.Colour.SRGB
                      Data.Colour.SRGB.Linear
