diff --git a/lens.cabal b/lens.cabal
--- a/lens.cabal
+++ b/lens.cabal
@@ -1,6 +1,6 @@
 name:          lens
 category:      Data, Lenses
-version:       0.2
+version:       0.3
 license:       BSD3
 cabal-version: >= 1.6
 license-file:  LICENSE
diff --git a/src/Control/Lens.hs b/src/Control/Lens.hs
--- a/src/Control/Lens.hs
+++ b/src/Control/Lens.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE RankNTypes, TemplateHaskell #-}
+{-# OPTIONS_GHC -Wall #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Control.Lens
@@ -16,17 +17,17 @@
 -- lens family libraries, such as lens-family, lens-family-core and
 -- lens-family-th, but the API is simpler.
 --
--- Note: If you merely want your library to provide lenses you may not have
--- to actually import _any_ lens library, for a "Lens Bar Foo", just export
+-- Note: If you merely want your library to _provide_ lenses you may not have
+-- to actually import _any_ lens library, for a @'Lens' Bar Foo@, just export
 -- a function with the signature:
 --
 -- > foo :: Functor f => (Foo -> f Foo) -> Bar -> f Bar
 --
--- and then you can compose it with other lenses using (.).
+-- and then you can compose it with other lenses using @(.)@.
 --
 -- This package provides lenses, lens families, setters, setter families,
 -- getters, multilenses, multi-getters, and multi-lens families in such
--- a way that they can all be composed automatically with (.).
+-- a way that they can all be composed automatically with @(.)@.
 --
 ----------------------------------------------------------------------------
 module Control.Lens
@@ -40,7 +41,7 @@
   , MultiLens
   , MultiLensFamily
 
-  -- * Constructing lenses
+  -- * Constructing Lenses
   , makeLenses
   , makeLensesBy
   , makeLensesFor
@@ -76,7 +77,7 @@
   -- * MultiGetters
   , folded
 
-  -- ** MultiGetter combinators
+  -- ** MultiGetterFamily Combinators
   , mapOf
   , foldMapOf
   , foldrOf
@@ -104,9 +105,10 @@
   , headML
   , tailML
   , leftML
+  , rightML
   , elementML
 
-  -- ** MultiLens combinators
+  -- ** MultiLens Combinators
   , traverseOf
   , mapMOf
   , sequenceAOf
@@ -140,35 +142,122 @@
 infix  4 ~=, %=, %%=, +=, -=, *=, //=, &&=, ||=
 infixr 0 ^$
 
-type Lens a b                = forall f. Functor f => (b -> f b) -> a -> f a
-type LensFamily a b c d      = forall f. Functor f => (c -> f d) -> a -> f b
-type Getter a b              = forall x y z. (b -> Const z x) -> a -> Const z y
-type Setter a b              = (b -> Identity b) -> a -> Identity a
-type SetterFamily a b c d    = (c -> Identity d) -> a -> Identity b
-type MultiGetter a c         = forall x y m. Monoid m => (c -> Const m x) -> a -> Const m y
-type MultiLens a b           = forall f. Applicative f => (b -> f b) -> a -> f a
-type MultiLensFamily a b c d = forall f. Applicative f => (c -> f d) -> a -> f b
+-- |
+-- A Lens is a purely functional reference to part of a data structure, it can be used to read or write to that part of the whole.
+--
+-- With great power comes great responsibility, and a 'Lens' is subject to the lens laws:
+--
+-- > reading l (writing l b a)   = b
+-- > writing l (reading l a) a   = a
+-- > writing l c (writing l b a) = writing l c a
+--
+-- Every 'Lens' can be used directly as a 'LensFamily' or as a 'Getter', 'Setter', or 'MultiLens', which transitively mens it can be used as
+-- almost anything! Such as a 'MultiLensFamily', a 'GetterFamily', a 'MultiGetterFamily', a 'MultiGetter', or a 'SetterFamily'.
+--
+-- > type Lens a b             = LensFamily a a b b
+--
+type Lens a b                  = forall f. Functor f => (b -> f b) -> a -> f a
 
--- | Build a lens from a getter and a setter
-lens :: Functor f => (a -> c) -> (d -> a -> b) -> (c -> f d) -> a -> f b
+-- | A LensFamily is a more general form of a Lens that permits polymorphic field updates
+--
+-- With great power comes great responsibility, and a 'LensFamily' is subject to the lens laws:
+--
+-- > reading l (writing l b a)   = b
+-- > writing l (reading l a) a   = a
+-- > writing l c (writing l b a) = writing l c a
+--
+-- These laws are strong enough that the 4 type parameters of a LensFamily cannot vary fully independently. For more on
+-- how they interact, read the "Why is it a Lens Family?" section of <http://comonad.com/reader/2012/mirrored-lenses/>.
+--
+-- Every 'LensFamily' can be used as a 'GetterFamily', a 'SetterFamily' or a 'MultiLensFamily', which transitively means it can be
+-- used as a 'MultiGetterFamily'.
+--
+-- Despite the complicated signature the pattern for implementing a 'LensFamily' is the same as a Lens.
+-- in fact the implementation doesn't change, the type signature merely generalizes.
+--
+-- > sndL :: LensFamily (c,a) (c,b) a b
+-- > sndL f (a,c) = (,) a <$> f c
+type LensFamily a b c d        = forall f. Functor f => (c -> f d) -> a -> f b
+
+-- | A 'SetterFamily' describes a way to perform polymorphic update to potentially multiple fields in a way that can be
+-- composed with other lens-like constructions that can be used as a 'SetterFamily'.
+--
+-- The typical way to obtain a 'SetterFamily' is to build one with 'setting' or to compose some other lens-like construction
+-- with a 'SetterFamily'.
+--
+-- Note: the only lens law that applies to a 'SetterFamily' is
+--
+-- > writing l c (writing l b a) = writing l c a
+--
+-- since 'reading' a SetterFamily doesn't work, so the other two laws can never be invoked.
+type SetterFamily a b c d           = (c -> Identity d) -> a -> Identity b
+
+-- | Every 'Setter' can be used directly as a 'SetterFamily'.
+--
+-- > type Setter a b                = SetterFamily a a b b
+type Setter a b                     = (b -> Identity b) -> a -> Identity a
+
+-- | A 'MultiGetterFamily' describes how to retrieve multiple values in a way that can be composed
+-- with other lens-like constructions.
+--
+-- A 'MultiGetterFamily a b c d' provides a structure with operations very similar to those of the 'Foldable'
+-- typeclass, see 'foldMapOf' and the other MultiGetterFamily combinators.
+--
+type MultiGetterFamily a b c d      = forall m. Monoid m => (c -> Const m d) -> a -> Const m b
+
+-- | Every 'MultiGetter' can be used directly as a 'MultiGetterFamily'.
+--
+--
+-- > type MultiGetter a b           = MultiGetterFamily a b c d
+type MultiGetter a b                = forall m. Monoid m => (b -> Const m b)-> a -> Const m a
+
+-- | A 'GetterFamily' describes how to retrieve a single value in a way that can be composed with
+-- other lens-like constructions. It can be used directly as a 'MultiGetterFamily', since it just
+-- ignores the 'Monoid'.
+type GetterFamily a b c d      = forall z. (c -> Const z d) -> a -> Const z b
+
+-- | A 'Getter' can be used directly as a 'GetterFamily' or as a 'MultiGetter', and hence it can be as a 'MutliGetterFamily'.
+--
+-- In general while your combinators may produce a 'Getter' it is better to consume any 'GetterFamily'.
+--
+-- > type Getter a b           = GetterFamily a a b b
+type Getter a b                = forall z. (b -> Const z b) -> a -> Const z a
+
+-- | A 'MultiLensFamily' can be used directly as a 'SetterFamily' or a 'MultiGetterFamily' and provides
+-- the ability to both read and update multiple fields, subject to the (relatively weak) MultiLensFamily laws.
+type MultiLensFamily a b c d        = forall f. Applicative f => (c -> f d) -> a -> f b
+
+-- | Every 'MultiLens' can be used as a 'MultiLensFamily' or a 'Setter' or 'MultiGetter', so it can transitively be used as a
+-- 'MultiGetterFamily' or 'SetterFamily' as well.
+--
+-- > type MultiLens a b             = MultiLensFamily a a b b
+type MultiLens a b                  = forall f. Applicative f => (b -> f b) -> a -> f a
+
+-- | Build a 'Lens' or 'LensFamily' from a getter and a setter
+--
+-- > lens :: Functor f => (a -> c) -> (d -> a -> b) -> (c -> f d) -> a -> f b
+lens :: (a -> c) -> (d -> a -> b) -> LensFamily a b c d
 lens ac dab cfd a = (`dab` a) <$> cfd (ac a)
 {-# INLINE lens #-}
 
--- | Built a lens from an isomorphism or an isomorphism family
-iso :: Functor f => (a -> c) -> (d -> b) -> (c -> f d) -> a -> f b
+-- | Built a 'Lens' or 'LensFamily' from an isomorphism or an isomorphism family
+--
+-- > iso :: Functor f => (a -> c) -> (d -> b) -> (c -> f d) -> a -> f b
+iso :: (a -> c) -> (d -> b) -> LensFamily a b c d
 iso f g h a = g <$> h (f a )
 {-# INLINE iso #-}
 
--- | Build a getter
-getting :: (a -> b) -> Getter a b
+-- | Build a Getter or GetterFamily
+getting :: (a -> c) -> GetterFamily a b c d
 getting f g a = Const (getConst (g (f a)))
 {-# INLINE getting #-}
 
--- | Building a multigetter
-gettingMany :: Foldable f => (a -> f b) -> MultiGetter a b
+-- | Building a MultiGetter or MultiGetterFamily
+gettingMany :: Foldable f => (a -> f c) -> MultiGetterFamily a b c d
 gettingMany f g a = Const (foldMap (getConst . g) (f a))
+{-# INLINE gettingMany #-}
 
--- | Build a setter
+-- | Build a Setter or SetterFamily
 setting :: ((c -> d) -> a -> b) -> SetterFamily a b c d
 setting f g a = Identity (f (runIdentity . g) a)
 {-# INLINE setting #-}
@@ -390,13 +479,16 @@
 
 instance Focus Strict.StateT where
   focus l (Strict.StateT m) = Strict.StateT $ \a -> unfocusing (l (Focusing . m) a)
+  {-# INLINE focus #-}
 
 instance Focus Lazy.StateT where
   focus l (Lazy.StateT m) = Lazy.StateT $ \a -> unfocusing (l (Focusing . m) a)
+  {-# INLINE focus #-}
 
 -- | We can focus Reader environments, too!
 instance Focus ReaderT where
   focus l (ReaderT m) = ReaderT $ \a -> liftM undefined $  unfocusing $ l (\b -> Focusing $ (\c -> (c,b)) `liftM` m b) a
+  {-# INLINE focus #-}
 
 -- | Set the value of a field in our monadic state
 (~=) :: MonadState a m => Setter a b -> b -> m ()
@@ -447,101 +539,111 @@
 -- Multigetter combinators
 --------------------------
 
--- | > foldMapOf :: Monoid m => MultiGetter a b -> (b -> m) -> a -> m
+-- | > foldMapOf :: Monoid m => MultiGetterFamily a b c d -> (c -> m) -> a -> m
 foldMapOf :: Monoid m => ((c -> Const m d) -> a -> Const m b) -> (c -> m) -> a -> m
 foldMapOf l f = getConst . l (Const . f)
 {-# INLINE foldMapOf #-}
 
--- | > foldOf :: Monoid m => MultiGetter a m -> a -> m
-foldOf :: Monoid m => ((m -> Const m n) -> a -> Const m b) -> a -> m
+-- | > foldOf :: Monoid m => MultiGetterFamily a b m d -> a -> m
+foldOf :: Monoid m => ((m -> Const m d) -> a -> Const m b) -> a -> m
 foldOf l = getConst . l Const
 {-# INLINE foldOf #-}
 
--- | > foldrOf :: MultiGetter a b -> (b -> c -> c) -> c -> a -> c
+-- | > foldrOf :: MultiGetterFamily a b c d -> (c -> e -> e) -> e -> a -> e
 foldrOf :: ((c -> Const (Endo e) d) -> a -> Const (Endo e) b) -> (c -> e -> e) -> e -> a -> e
 foldrOf l f z t = appEndo (foldMapOf l (Endo . f) t) z
 {-# INLINE foldrOf #-}
 
--- | > toListOf :: MultiGetter a b -> a -> [b]
+-- | > toListOf :: MultiGetterFamily a b c d -> a -> [c]
 toListOf :: ((c -> Const [c] d) -> a -> Const [c] b) -> a -> [c]
 toListOf l = foldMapOf l return
 {-# INLINE toListOf #-}
 
+-- | > andOf :: MultiGetterFamily a b Bool d -> a -> Bool
 andOf :: ((Bool -> Const All d) -> a -> Const All b) -> a -> Bool
 andOf l = getAll . foldMapOf l All
 {-# INLINE andOf #-}
 
+-- | > orOf :: MultiGetterFamily a b Bool d -> a -> Bool
 orOf :: ((Bool -> Const Any d) -> a -> Const Any b) -> a -> Bool
 orOf l = getAny . foldMapOf l Any
 {-# INLINE orOf #-}
 
--- | > anyOf :: MultiGetter a b -> (b -> Bool) -> a -> Bool
+-- | > anyOf :: MultiGetterFamily a b c d -> (c -> Bool) -> a -> Bool
 anyOf :: ((c -> Const Any d) -> a -> Const Any b) -> (c -> Bool) -> a -> Bool
 anyOf l f = getAny . foldMapOf l (Any . f)
 {-# INLINE anyOf #-}
 
--- | > allOf :: MultiGetter a b -> (b -> Bool) -> a -> Bool
+-- | > allOf :: MultiGetterFamily a b c d -> (c -> Bool) -> a -> Bool
 allOf :: ((c -> Const All d) -> a -> Const All b) -> (c -> Bool) -> a -> Bool
 allOf l f = getAll . foldMapOf l (All . f)
 {-# INLINE allOf #-}
 
+-- | > productOf ::  Num c => MultiGetterFamily a b c d -> a -> c
 productOf :: Num c => ((c -> Const (Product c) d) -> a -> Const (Product c) b) -> a -> c
 productOf l = getProduct . foldMapOf l Product
 {-# INLINE productOf #-}
 
+-- | > sumOf ::  Num c => MultiGetterFamily a b c d -> a -> c
 sumOf ::  Num c => ((c -> Const (Sum c) d) -> a -> Const (Sum c) b) -> a -> c
 sumOf l = getSum . foldMapOf l Sum
 {-# INLINE sumOf #-}
 
--- | > traverseOf_ :: Applicative f => MultiGetter a b -> (b -> f c) -> a -> f ()
+-- | > traverseOf_ :: Applicative f => MultiGetterFamily a b c d -> (c -> f e) -> a -> f ()
 traverseOf_ :: Applicative f => ((c -> Const (Traversal f) d) -> a -> Const (Traversal f) b) -> (c -> f e) -> a -> f ()
 traverseOf_ l f = getTraversal . foldMapOf l (Traversal . (() <$) . f)
 {-# INLINE traverseOf_ #-}
 
--- | > forOf_ :: Applicative f => MultiGetter a b -> a -> (b -> f c) -> f ()
+-- | > forOf_ :: Applicative f => MultiGetterFamily a b c d -> a -> (c -> f e) -> f ()
 forOf_ :: Applicative f => ((c -> Const (Traversal f) d) -> a -> Const (Traversal f) b) -> a -> (c -> f e) -> f ()
 forOf_ l a f = traverseOf_ l f a
 {-# INLINE forOf_ #-}
 
--- | > sequenceAOf_ :: Applicative f => MultiGetter a (f ()) -> a -> f ()
-sequenceAOf_ :: Applicative f => ((f () -> Const (Traversal f) d) -> a -> Const (Traversal f) e) -> a -> f ()
+-- | > sequenceAOf_ :: Applicative f => MultiGetterFamily a b (f ()) d -> a -> f ()
+sequenceAOf_ :: Applicative f => ((f () -> Const (Traversal f) d) -> a -> Const (Traversal f) b) -> a -> f ()
 sequenceAOf_ l = getTraversal . foldMapOf l (Traversal . (() <$))
 {-# INLINE sequenceAOf_ #-}
 
--- | > mapMOf_ :: Monad m => MultiGetter a b -> (b -> m c) -> a -> m ()
+-- | > mapMOf_ :: Monad m => MultiGetterFamily a b c d -> (c -> m e) -> a -> m ()
 mapMOf_ :: Monad m => ((c -> Const (Traversal (WrappedMonad m)) d) -> a -> Const (Traversal (WrappedMonad m)) b) -> (c -> m e) -> a -> m ()
 mapMOf_ l f = unwrapMonad . traverseOf_ l (WrapMonad . f)
 {-# INLINE mapMOf_ #-}
 
--- | > forMOf_ :: Monad m => MultiGetter a b -> a -> (b -> m c) -> m ()
+-- | > forMOf_ :: Monad m => MultiGetterFamily a b c d -> a -> (c -> m e) -> m ()
 forMOf_ :: Monad m => ((c -> Const (Traversal (WrappedMonad m)) d) -> a -> Const (Traversal (WrappedMonad m)) b) -> a -> (c -> m e) -> m ()
 forMOf_ l a f = mapMOf_ l f a
 {-# INLINE forMOf_ #-}
 
--- | > sequenceOf_ :: Monad m => MultiGetter a (m b) -> a -> m ()
+-- | > sequenceOf_ :: Monad m => MultiGetterFamily a b (m b) d -> a -> m ()
 sequenceOf_ :: Monad m => ((m c -> Const (Traversal (WrappedMonad m)) d) -> a -> Const (Traversal (WrappedMonad m)) b) -> a -> m ()
 sequenceOf_ l = unwrapMonad . traverseOf_ l WrapMonad
 {-# INLINE sequenceOf_ #-}
 
 -- | The sum of a collection of actions, generalizing 'concatOf'.
+--
+-- > asumOf :: Alternative f => MultiGetterFamily a b c d -> a -> f c
 asumOf :: Alternative f => ((f c -> Const (Endo (f c)) d) -> a -> Const (Endo (f c)) b) -> a -> f c
 asumOf l = foldrOf l (<|>) Applicative.empty
 {-# INLINE asumOf #-}
 
 -- | The sum of a collection of actions, generalizing 'concatOf'.
+--
+-- > msumOf :: MonadPlus m => MultiGetterFamily a b c d -> a -> m c
 msumOf :: MonadPlus m => ((m c -> Const (Endo (m c)) d) -> a -> Const (Endo (m c)) b) -> a -> m c
 msumOf l = foldrOf l mplus mzero
 {-# INLINE msumOf #-}
 
+-- | > elemOf :: Eq c => MultiGetterFamily a b c d -> c -> a -> Bool
 elemOf :: Eq c => ((c -> Const Any d) -> a -> Const Any b) -> c -> a -> Bool
 elemOf l = anyOf l . (==)
 {-# INLINE elemOf #-}
 
+-- | > notElemOf :: Eq c => MultiGetterFamily a b c d -> c -> a -> Bool
 notElemOf :: Eq c => ((c -> Const Any d) -> a -> Const Any b) -> c -> a -> Bool
 notElemOf l c = not . elemOf l c
 {-# INLINE notElemOf #-}
 
--- | concatMapOf :: MultiGetter a c -> (c -> [e]) -> a -> [e]
+-- | > concatMapOf :: MultiGetterFamily a b c d -> (c -> [e]) -> a -> [e]
 concatMapOf :: ((c -> Const [e] d) -> a -> Const [e] b) -> (c -> [e]) -> a -> [e]
 concatMapOf l ces a = getConst  (l (Const . ces) a)
 {-# INLINE concatMapOf #-}
@@ -574,7 +676,7 @@
 -- Multigetters
 --------------------------
 
-folded :: Foldable f => MultiGetter (f a) a
+folded :: Foldable f => MultiGetterFamily (f c) b c d
 folded = gettingMany id
 {-# INLINE folded #-}
 
@@ -583,34 +685,64 @@
 --------------------------
 
 -- | This is the partial lens that never succeeds at returning any values
-constML :: Applicative f => (c -> f d) -> a -> f a
+--
+-- > constML :: Applicative f => (c -> f d) -> a -> f a
+constML :: MultiLensFamily a a c d
 constML = const pure
 {-# INLINE constML #-}
 
-headML :: Applicative f => (a -> f a) -> [a] -> f [a]
+-- The multilens for reading and writing to the head of a list
+--
+-- | > headML :: Applicative f => (a -> f a) -> [a] -> f [a]
+headML :: MultiLens [a] a
 headML _ [] = pure []
 headML f (a:as) = (:as) <$> f a
 {-# INLINE headML #-}
 
-tailML :: Applicative f => ([a] -> f [a]) -> [a] -> f [a]
+-- The multilens for reading and writing to the tail of a list
+--
+-- | > tailML :: Applicative f => ([a] -> f [a]) -> [a] -> f [a]
+tailML :: MultiLens [a] [a]
 tailML _ [] = pure []
 tailML f (a:as) = (a:) <$> f as
 {-# INLINE tailML #-}
 
-leftML :: Applicative f => (a -> f b) -> Either a c -> f (Either b c)
+-- | A multilens for tweaking the left-hand value in an Either:
+--
+-- > leftML :: Applicative f => (a -> f b) -> Either a c -> f (Either b c)
+leftML :: MultiLensFamily (Either a c) (Either b c) a b
 leftML f (Left a)  = Left <$> f a
 leftML _ (Right c) = pure $ Right c
 {-# INLINE leftML #-}
 
-keyML :: (Applicative f, Ord k) => k -> (v -> f v) -> Map k v -> f (Map k v)
+-- | A multilens for tweaking the right-hand value in an Either:
+--
+-- > rightML :: Applicative f => (a -> f b) -> Either c a -> f (Either c a)
+-- > rightML = traverse
+--
+-- Unfortunately the instance for 'Traversable (Either c)' is still missing from
+-- base.
+rightML :: MultiLensFamily (Either c a) (Either c b) a b
+rightML _ (Left c) = pure $ Left c
+rightML f (Right a) = Right <$> f a
+{-# INLINE rightML #-}
+
+-- |
+-- > keyML :: (Applicative f, Ord k) => k -> (v -> f v) -> Map k v -> f (Map k v)
+-- > keyML k = keyL k . traverse
+keyML :: Ord k => k -> MultiLens (Map k v) v
 keyML k = keyL k . traverse
 {-# INLINE keyML #-}
 
-intKeyML :: Applicative f => Int -> (v -> f v) -> IntMap v -> f (IntMap v)
+-- |
+-- > intKeyML :: Applicative f => Int -> (v -> f v) -> IntMap v -> f (IntMap v)
+-- > intKeyML k = intKeyL k . traverse
+intKeyML :: Int -> MultiLens (IntMap v) v
 intKeyML k = intKeyL k . traverse
 {-# INLINE intKeyML #-}
 
-elementML :: (Applicative f, Traversable t) => Int -> (a -> f a) -> t a -> f (t a)
+-- | > elementML :: (Applicative f, Traversable t) => Int -> (a -> f a) -> t a -> f (t a)
+elementML :: Traversable t => Int -> MultiLens (t a) a
 elementML j f ta = fst (runSA (traverse go ta) 0) where
   go a = SA $ \i -> (if i == j then f a else pure a, i + 1)
 {-# INLINE elementML #-}
