diff --git a/examples/pong.hs b/examples/pong.hs
--- a/examples/pong.hs
+++ b/examples/pong.hs
@@ -14,8 +14,8 @@
 
 import Control.Applicative ((<$>), (<*>))
 import Control.Lens
-import Control.Lens.TH (makeLenses)
-import Control.Monad.State
+import Control.Monad.State (State, execState, get)
+import Control.Monad (when)
 
 import Data.Set (Set, member, empty, insert, delete)
 import Data.Set.Lens (contains)
@@ -24,7 +24,7 @@
 import Graphics.Gloss
 import Graphics.Gloss.Interface.Pure.Game
 
-import System.Random
+import System.Random (randomRs, getStdGen)
 
 -- Some global constants
 
diff --git a/lens.cabal b/lens.cabal
--- a/lens.cabal
+++ b/lens.cabal
@@ -1,6 +1,6 @@
 name:          lens
 category:      Data, Lenses
-version:       1.9.1
+version:       2.0
 license:       BSD3
 cabal-version: >= 1.8
 license-file:  LICENSE
@@ -33,7 +33,7 @@
   .
   The core of this hierarchy looks like:
   .
-  <<https://github.com/ekmett/lens/wiki/images/Hierarchy-1.9.png>>
+  <<https://github.com/ekmett/lens/wiki/images/Hierarchy-2.0.png>>
   .
   You can compose any two elements of the hierarchy above using (.) from the Prelude, and you can
   use any element of the hierarchy as any type it links to above it.
diff --git a/src/Control/Lens/Fold.hs b/src/Control/Lens/Fold.hs
--- a/src/Control/Lens/Fold.hs
+++ b/src/Control/Lens/Fold.hs
@@ -67,8 +67,6 @@
   , foldrOf', foldlOf'
   , foldr1Of, foldl1Of
   , foldrMOf, foldlMOf
-  -- * Implementation Details
-  , noEffect
   ) where
 
 import Control.Applicative as Applicative
@@ -221,10 +219,10 @@
 --
 -- @
 -- foldMapOf ::             'Getter' a c           -> (c -> r) -> a -> r
--- foldMapOf :: Monoid r => 'Fold' a c             -> (c -> r) -> a -> r
+-- foldMapOf :: 'Monoid' r => 'Fold' a c             -> (c -> r) -> a -> r
 -- foldMapOf ::             'Simple' 'Lens' a c      -> (c -> r) -> a -> r
 -- foldMapOf ::             'Simple' 'Control.Lens.Iso.Iso' a c       -> (c -> r) -> a -> r
--- foldMapOf :: Monoid r => 'Simple' 'Control.Lens.Traversal.Traversal' a c -> (c -> r) -> a -> r
+-- foldMapOf :: 'Monoid' r => 'Simple' 'Control.Lens.Traversal.Traversal' a c -> (c -> r) -> a -> r
 -- @
 foldMapOf :: Getting r a c -> (c -> r) -> a -> r
 foldMapOf l f = runAccessor . l (Accessor . f)
@@ -240,7 +238,7 @@
 -- foldOf :: 'Monoid' m => 'Fold' a m             -> a -> m
 -- foldOf ::             'Simple' 'Lens' a m      -> a -> m
 -- foldOf ::             'Simple' 'Control.Lens.Iso.Iso' a m       -> a -> m
--- foldOf :: 'Monoid m' => 'Simple' 'Control.Lens.Traversal.Traversal' a m -> a -> m
+-- foldOf :: 'Monoid' m => 'Simple' 'Control.Lens.Traversal.Traversal' a m -> a -> m
 -- @
 foldOf :: Getting c a c -> a -> c
 foldOf l = runAccessor . l Accessor
@@ -296,10 +294,10 @@
 -- @'Data.Foldable.and' = 'andOf' 'folded'@
 --
 -- @
--- andOf :: 'Getter' a 'Bool'          -> a -> 'Bool'
--- andOf :: 'Fold' a 'Bool'            -> a -> 'Bool'
--- andOf :: 'Simple' 'Lens' a 'Bool'     -> a -> 'Bool'
--- andOf :: 'Simple' 'Control.Lens.Iso.Iso' a 'Bool'      -> a -> 'Bool'
+-- andOf :: 'Getter' a 'Bool'           -> a -> 'Bool'
+-- andOf :: 'Fold' a 'Bool'             -> a -> 'Bool'
+-- andOf :: 'Simple' 'Lens' a 'Bool'      -> a -> 'Bool'
+-- andOf :: 'Simple' 'Control.Lens.Iso.Iso' a 'Bool'       -> a -> 'Bool'
 -- andOf :: 'Simple' 'Control.Lens.Traversal.Traversal' a 'Bool' -> a -> 'Bool'
 -- @
 andOf :: Getting All a Bool -> a -> Bool
@@ -310,10 +308,10 @@
 -- @'Data.Foldable.or' = 'orOf' 'folded'@
 --
 -- @
--- orOf :: 'Getter' a 'Bool'          -> a -> 'Bool'
--- orOf :: 'Fold' a 'Bool'            -> a -> 'Bool'
--- orOf :: 'Simple' 'Lens' a 'Bool'     -> a -> 'Bool'
--- orOf :: 'Simple' 'Control.Lens.Iso.Iso' a 'Bool'      -> a -> 'Bool'
+-- orOf :: 'Getter' a 'Bool'           -> a -> 'Bool'
+-- orOf :: 'Fold' a 'Bool'             -> a -> 'Bool'
+-- orOf :: 'Simple' 'Lens' a 'Bool'      -> a -> 'Bool'
+-- orOf :: 'Simple' 'Control.Lens.Iso.Iso' a 'Bool'       -> a -> 'Bool'
 -- orOf :: 'Simple' 'Control.Lens.Traversal.Traversal' a 'Bool' -> a -> 'Bool'
 -- @
 orOf :: Getting Any a Bool -> a -> Bool
@@ -324,8 +322,8 @@
 -- @'Data.Foldable.any' = 'anyOf' 'folded'@
 --
 -- @
--- anyOf :: 'Getter' a c           -> (c -> 'Bool') -> a -> 'Bool'
--- anyOf :: 'Fold' a c             -> (c -> 'Bool') -> a -> 'Bool'
+-- anyOf :: 'Getter' a c               -> (c -> 'Bool') -> a -> 'Bool'
+-- anyOf :: 'Fold' a c                 -> (c -> 'Bool') -> a -> 'Bool'
 -- anyOf :: 'Simple' 'Lens' a b c d      -> (c -> 'Bool') -> a -> 'Bool'
 -- anyOf :: 'Simple' 'Control.Lens.Iso.Iso' a b c d       -> (c -> 'Bool') -> a -> 'Bool'
 -- anyOf :: 'Simple' 'Control.Lens.Traversal.Traversal' a b c d -> (c -> 'Bool') -> a -> 'Bool'
@@ -338,8 +336,8 @@
 -- @'Data.Foldable.all' = 'allOf' 'folded'@
 --
 -- @
--- allOf :: 'Getter' a c              -> (c -> 'Bool') -> a -> 'Bool'
--- allOf :: 'Fold' a c                -> (c -> 'Bool') -> a -> 'Bool'
+-- allOf :: 'Getter' a c           -> (c -> 'Bool') -> a -> 'Bool'
+-- allOf :: 'Fold' a c             -> (c -> 'Bool') -> a -> 'Bool'
 -- allOf :: 'Simple' 'Lens' a c      -> (c -> 'Bool') -> a -> 'Bool'
 -- allOf :: 'Simple' 'Control.Lens.Iso.Iso' a c       -> (c -> 'Bool') -> a -> 'Bool'
 -- allOf :: 'Simple' 'Control.Lens.Traversal.Traversal' a c -> (c -> 'Bool') -> a -> 'Bool'
@@ -354,9 +352,9 @@
 -- @
 -- productOf ::          'Getter' a c           -> a -> c
 -- productOf :: 'Num' c => 'Fold' a c             -> a -> c
--- productOf ::          'Control.'Lens'.Type.Simple' 'Lens' a c      -> a -> c
--- productOf ::          'Control.'Lens'.Type.Simple' 'Control.Lens.Iso.Iso' a c       -> a -> c
--- productOf :: 'Num' c => 'Control.'Lens'.Type.Simple' 'Control.Lens.Traversal.Traversal' a c -> a -> c
+-- productOf ::          'Simple' 'Lens' a c      -> a -> c
+-- productOf ::          'Simple' 'Control.Lens.Iso.Iso' a c       -> a -> c
+-- productOf :: 'Num' c => 'Simple' 'Control.Lens.Traversal.Traversal' a c -> a -> c
 -- @
 productOf :: Getting (Product c) a c -> a -> c
 productOf l = getProduct . foldMapOf l Product
@@ -370,11 +368,11 @@
 -- @'sumOf' ('folded' . '_1') :: ('Foldable' f, 'Num' a) => f (a, b) -> a@
 --
 -- @
--- sumOf ::          'Getter' a c        -> a -> c
--- sumOf :: Num c => 'Fold' a c          -> a -> c
+-- sumOf ::          'Getter' a c           -> a -> c
+-- sumOf :: 'Num' c => 'Fold' a c             -> a -> c
 -- sumOf ::          'Simple' 'Lens' a c      -> a -> c
 -- sumOf ::          'Simple' 'Control.Lens.Iso.Iso' a c       -> a -> c
--- sumOf :: Num c => 'Simple' 'Control.Lens.Traversal.Traversal' a c -> a -> c
+-- sumOf :: 'Num' c => 'Simple' 'Control.Lens.Traversal.Traversal' a c -> a -> c
 -- @
 sumOf :: Getting (Sum c) a c -> a -> c
 sumOf l = getSum . foldMapOf l Sum
@@ -422,11 +420,13 @@
 -- |
 -- @'sequenceA_' = 'sequenceAOf_' 'folded'@
 --
--- sequenceAOf_ :: 'Functor' f     => 'Getter' a (f ())        -> a -> f ()
--- sequenceAOf_ :: 'Applicative' f => Fold a (f ())          -> a -> f ()
+-- @
+-- sequenceAOf_ :: 'Functor' f     => 'Getter' a (f ())           -> a -> f ()
+-- sequenceAOf_ :: 'Applicative' f => 'Fold' a (f ())             -> a -> f ()
 -- sequenceAOf_ :: 'Functor' f     => 'Simple' 'Lens' a (f ())      -> a -> f ()
--- sequenceAOf_ :: 'Functor' f     => 'Simple' 'Iso a (f ())       -> a -> f ()
+-- sequenceAOf_ :: 'Functor' f     => 'Simple' 'Iso' a (f ())       -> a -> f ()
 -- sequenceAOf_ :: 'Applicative' f => 'Simple' 'Control.Lens.Traversal.Traversal' a (f ()) -> a -> f ()
+-- @
 sequenceAOf_ :: Functor f => Getting (Traversed f) a (f ()) -> a -> f ()
 sequenceAOf_ l = getTraversed . foldMapOf l (Traversed . void)
 {-# INLINE sequenceAOf_ #-}
@@ -434,11 +434,13 @@
 -- |
 -- @'Data.Foldable.mapM_' = 'mapMOf_' 'folded'@
 --
--- > mapMOf_ :: 'Monad' m => 'Getter' a c        -> (c -> m e) -> a -> m ()
--- > mapMOf_ :: 'Monad' m => 'Fold' a c          -> (c -> m e) -> a -> m ()
--- > mapMOf_ :: 'Monad' m => 'Simple' 'Lens' a c      -> (c -> m e) -> a -> m ()
--- > mapMOf_ :: 'Monad' m => 'Simple' 'Control.Lens.Iso.Iso' a c       -> (c -> m e) -> a -> m ()
--- > mapMOf_ :: 'Monad' m => 'Simple' 'Control.Lens.Traversal.Traversal' a c -> (c -> m e) -> a -> m ()
+-- @
+-- mapMOf_ :: 'Monad' m => 'Getter' a c           -> (c -> m e) -> a -> m ()
+-- mapMOf_ :: 'Monad' m => 'Fold' a c             -> (c -> m e) -> a -> m ()
+-- mapMOf_ :: 'Monad' m => 'Simple' 'Lens' a c      -> (c -> m e) -> a -> m ()
+-- mapMOf_ :: 'Monad' m => 'Simple' 'Control.Lens.Iso.Iso' a c       -> (c -> m e) -> a -> m ()
+-- mapMOf_ :: 'Monad' m => 'Simple' 'Control.Lens.Traversal.Traversal' a c -> (c -> m e) -> a -> m ()
+-- @
 mapMOf_ :: Monad m => Getting (Sequenced m) a c -> (c -> m e) -> a -> m ()
 mapMOf_ l f = getSequenced . foldMapOf l (Sequenced . liftM skip . f)
 {-# INLINE mapMOf_ #-}
@@ -450,11 +452,13 @@
 -- |
 -- @'Data.Foldable.forM_' = 'forMOf_' 'folded'@
 --
--- > forMOf_ :: 'Monad' m => 'Getter' a c           -> a -> (c -> m e) -> m ()
--- > forMOf_ :: 'Monad' m => 'Fold' a c             -> a -> (c -> m e) -> m ()
--- > forMOf_ :: 'Monad' m => 'Simple' 'Lens' a c      -> a -> (c -> m e) -> m ()
--- > forMOf_ :: 'Monad' m => 'Simple' 'Control.Lens.Iso.Iso' a c       -> a -> (c -> m e) -> m ()
--- > forMOf_ :: 'Monad' m => 'Simple' 'Control.Lens.Traversal.Traversal' a c -> a -> (c -> m e) -> m ()
+-- @
+-- forMOf_ :: 'Monad' m => 'Getter' a c           -> a -> (c -> m e) -> m ()
+-- forMOf_ :: 'Monad' m => 'Fold' a c             -> a -> (c -> m e) -> m ()
+-- forMOf_ :: 'Monad' m => 'Simple' 'Lens' a c      -> a -> (c -> m e) -> m ()
+-- forMOf_ :: 'Monad' m => 'Simple' 'Control.Lens.Iso.Iso' a c       -> a -> (c -> m e) -> m ()
+-- forMOf_ :: 'Monad' m => 'Simple' 'Control.Lens.Traversal.Traversal' a c -> a -> (c -> m e) -> m ()
+-- @
 forMOf_ :: Monad m => Getting (Sequenced m) a c -> a -> (c -> m e) -> m ()
 forMOf_ = flip . mapMOf_
 {-# INLINE forMOf_ #-}
@@ -463,8 +467,8 @@
 -- @'Data.Foldable.sequence_' = 'sequenceOf_' 'folded'@
 --
 -- @
--- sequenceOf_ :: 'Monad' m => 'Getter' a (m b)        -> a -> m ()
--- sequenceOf_ :: 'Monad' m => 'Fold' a (m b)          -> a -> m ()
+-- sequenceOf_ :: 'Monad' m => 'Getter' a (m b)           -> a -> m ()
+-- sequenceOf_ :: 'Monad' m => 'Fold' a (m b)             -> a -> m ()
 -- sequenceOf_ :: 'Monad' m => 'Simple' 'Lens' a (m b)      -> a -> m ()
 -- sequenceOf_ :: 'Monad' m => 'Simple' 'Control.Lens.Iso.Iso' a (m b)       -> a -> m ()
 -- sequenceOf_ :: 'Monad' m => 'Simple' 'Control.Lens.Traversal.Traversal' a (m b) -> a -> m ()
@@ -478,8 +482,8 @@
 -- @'asum' = 'asumOf' 'folded'@
 --
 -- @
--- asumOf :: 'Alternative' f => 'Getter' a c        -> a -> f c
--- asumOf :: 'Alternative' f => 'Fold' a c          -> a -> f c
+-- asumOf :: 'Alternative' f => 'Getter' a c           -> a -> f c
+-- asumOf :: 'Alternative' f => 'Fold' a c             -> a -> f c
 -- asumOf :: 'Alternative' f => 'Simple' 'Lens' a c      -> a -> f c
 -- asumOf :: 'Alternative' f => 'Simple' 'Control.Lens.Iso.Iso' a c       -> a -> f c
 -- asumOf :: 'Alternative' f => 'Simple' 'Control.Lens.Traversal.Traversal' a c -> a -> f c
@@ -493,8 +497,8 @@
 -- @'msum' = 'msumOf' 'folded'@
 --
 -- @
--- msumOf :: 'MonadPlus' m => 'Getter' a c        -> a -> m c
--- msumOf :: 'MonadPlus' m => 'Fold' a c          -> a -> m c
+-- msumOf :: 'MonadPlus' m => 'Getter' a c           -> a -> m c
+-- msumOf :: 'MonadPlus' m => 'Fold' a c             -> a -> m c
 -- msumOf :: 'MonadPlus' m => 'Simple' 'Lens' a c      -> a -> m c
 -- msumOf :: 'MonadPlus' m => 'Simple' 'Control.Lens.Iso.Iso' a c       -> a -> m c
 -- msumOf :: 'MonadPlus' m => 'Simple' 'Control.Lens.Traversal.Traversal' a c -> a -> m c
@@ -628,8 +632,8 @@
 -- @'nullOf' ('folded' . '_1' . 'folded') :: 'Foldable' f => f (g a, b) -> 'Bool'@
 --
 -- @
--- nullOf :: 'Getter' a c          -> a -> 'Bool'
--- nullOf :: 'Fold' a c            -> a -> 'Bool'
+-- nullOf :: 'Getter' a c           -> a -> 'Bool'
+-- nullOf :: 'Fold' a c             -> a -> 'Bool'
 -- nullOf :: 'Simple' 'Control.Lens.Iso.Iso' a c       -> a -> 'Bool'
 -- nullOf :: 'Simple' 'Lens' a c      -> a -> 'Bool'
 -- nullOf :: 'Simple' 'Control.Lens.Traversal.Traversal' a c -> a -> 'Bool'
@@ -681,8 +685,8 @@
 -- @'Data.Foldable.maximumBy' cmp = 'Data.Maybe.fromMaybe' ('error' "empty") . 'maximumByOf' 'folded' cmp@
 --
 -- @
--- maximumByOf :: 'Getter' a c        -> (c -> c -> 'Ordering') -> a -> 'Maybe' c
--- maximumByOf :: 'Fold' a c          -> (c -> c -> 'Ordering') -> a -> 'Maybe' c
+-- maximumByOf :: 'Getter' a c           -> (c -> c -> 'Ordering') -> a -> 'Maybe' c
+-- maximumByOf :: 'Fold' a c             -> (c -> c -> 'Ordering') -> a -> 'Maybe' c
 -- maximumByOf :: 'Simple' 'Control.Lens.Iso.Iso' a c       -> (c -> c -> 'Ordering') -> a -> 'Maybe' c
 -- maximumByOf :: 'Simple' 'Lens' a c      -> (c -> c -> 'Ordering') -> a -> 'Maybe' c
 -- maximumByOf :: 'Simple' 'Control.Lens.Traversal.Traversal' a c -> (c -> c -> 'Ordering') -> a -> 'Maybe' c
@@ -778,8 +782,8 @@
 -- @'Data.Foldable.foldr'' = 'foldrOf'' 'folded'@
 --
 -- @
--- foldrOf' :: 'Getter' a c        -> (c -> e -> e) -> e -> a -> e
--- foldrOf' :: 'Fold' a c          -> (c -> e -> e) -> e -> a -> e
+-- foldrOf' :: 'Getter' a c           -> (c -> e -> e) -> e -> a -> e
+-- foldrOf' :: 'Fold' a c             -> (c -> e -> e) -> e -> a -> e
 -- foldrOf' :: 'Simple' 'Control.Lens.Iso.Iso' a c       -> (c -> e -> e) -> e -> a -> e
 -- foldrOf' :: 'Simple' 'Lens' a c      -> (c -> e -> e) -> e -> a -> e
 -- foldrOf' :: 'Simple' 'Control.Lens.Traversal.Traversal' a c -> (c -> e -> e) -> e -> a -> e
diff --git a/src/Control/Lens/IndexedLens.hs b/src/Control/Lens/IndexedLens.hs
--- a/src/Control/Lens/IndexedLens.hs
+++ b/src/Control/Lens/IndexedLens.hs
@@ -56,8 +56,8 @@
 -- If you do not need the intermediate result, you can use ('Control.Lens.Type.%@~') or even ('Control.Lens.Type.%~').
 --
 -- @
--- (<%@~) ::             'IndexedLens' i a b c d -> (i -> c -> d) -> a -> (d, b)
--- (<%@~) :: 'Monoid' d => 'Control.Lens.IndexedTraversal.IndexedTraversal' i a b c d -> (i -> c -> d) -> a -> (d, b)
+-- (\<%\@~) ::             'IndexedLens' i a b c d -> (i -> c -> d) -> a -> (d, b)
+-- (\<%\@~) :: 'Monoid' d => 'Control.Lens.IndexedTraversal.IndexedTraversal' i a b c d -> (i -> c -> d) -> a -> (d, b)
 -- @
 (<%@~) :: Overloaded (Index i) ((,)d) a b c d -> (i -> c -> d) -> a -> (d, b)
 l <%@~ f = withIndex l $ \i c -> let d = f i c in (d, d)
@@ -70,16 +70,16 @@
 -- @('%%@~') = 'withIndex'@
 --
 -- @
--- (%%@~) :: 'Functor' f => 'IndexedLens' i a b c d      -> (i -> c -> f d) -> a -> f b
--- (%%@~) :: 'Functor' f => 'Control.Lens.IndexedTraversal.IndexedTraversal' i a b c d -> (i -> c -> f d) -> a -> f b
+-- (%%\@~) :: 'Functor' f => 'IndexedLens' i a b c d      -> (i -> c -> f d) -> a -> f b
+-- (%%\@~) :: 'Functor' f => 'Control.Lens.IndexedTraversal.IndexedTraversal' i a b c d -> (i -> c -> f d) -> a -> f b
 -- @
 --
 -- In particular, it is often useful to think of this function as having one of these even more 
 -- restrictive type signatures
 --
 -- @
--- (%%@~) ::             'IndexedLens' i a b c d      -> (i -> c -> (e, d)) -> a -> (e, b)
--- (%%@~) :: 'Monoid' e => 'Control.Lens.IndexedTraversal.IndexedTraversal' i a b c d -> (i -> c -> (e, d)) -> a -> (e, b)
+-- (%%\@~) ::             'IndexedLens' i a b c d      -> (i -> c -> (e, d)) -> a -> (e, b)
+-- (%%\@~) :: 'Monoid' e => 'Control.Lens.IndexedTraversal.IndexedTraversal' i a b c d -> (i -> c -> (e, d)) -> a -> (e, b)
 -- @
 (%%@~) :: Overloaded (Index i) f a b c d -> (i -> c -> f d) -> a -> f b
 (%%@~) = withIndex
@@ -92,8 +92,8 @@
 -- @l '%%@=' f = 'state' (l '%%@~' f)@
 --
 -- @
--- (%%@=) :: 'MonadState' a m                'IndexedLens' i a a c d      -> (i -> c -> (e, d)) -> a -> m e
--- (%%@=) :: ('MonadState' a m, 'Monoid' e) => 'Control.Lens.IndexedTraversal.IndexedTraversal' i a a c d -> (i -> c -> (e, d)) -> a -> m e
+-- (%%\@=) :: 'MonadState' a m                'IndexedLens' i a a c d      -> (i -> c -> (e, d)) -> a -> m e
+-- (%%\@=) :: ('MonadState' a m, 'Monoid' e) => 'Control.Lens.IndexedTraversal.IndexedTraversal' i a a c d -> (i -> c -> (e, d)) -> a -> m e
 -- @
 (%%@=) :: MonadState a m => Overloaded (Index i) ((,)e) a a c d -> (i -> c -> (e, d)) -> m e
 #if MIN_VERSION_mtl(2,1,0)
@@ -111,8 +111,8 @@
 -- return a monoidal summary of the intermediate results.
 --
 -- @
--- (<%@=) :: 'MonadState' a m                'IndexedLens' i a a c d      -> (i -> c -> d) -> a -> m d
--- (<%@=) :: ('MonadState' a m, 'Monoid' e) => 'Control.Lens.IndexedTraversal.IndexedTraversal' i a a c d -> (i -> c -> d) -> a -> m d
+-- (\<%\@=) :: 'MonadState' a m                'IndexedLens' i a a c d      -> (i -> c -> d) -> a -> m d
+-- (\<%\@=) :: ('MonadState' a m, 'Monoid' e) => 'Control.Lens.IndexedTraversal.IndexedTraversal' i a a c d -> (i -> c -> d) -> a -> m d
 -- @
 (<%@=) :: MonadState a m => Overloaded (Index i) ((,)d) a a c d -> (i -> c -> d) -> m d
 l <%@= f = l %%@= \ i c -> let d = f i c in (d, d)
diff --git a/src/Control/Lens/TH.hs b/src/Control/Lens/TH.hs
--- a/src/Control/Lens/TH.hs
+++ b/src/Control/Lens/TH.hs
@@ -282,7 +282,7 @@
         clause [varP f, conP conName $ map varP names] (normalB
                (appsE [ varE (mkName "fmap")
                       , lamE [varP x] $ appsE $ conE conName : map varE (element i .~ x $ names)
-                      , varE (mkName "f") `appE` varE (names^.element i)
+                      , varE f `appE` varE (names^.element i)
                       ])) []
       Nothing -> errorClause lensName fieldName conName
     clauses con = errorClause lensName fieldName (con^.name)
diff --git a/src/Control/Lens/Type.hs b/src/Control/Lens/Type.hs
--- a/src/Control/Lens/Type.hs
+++ b/src/Control/Lens/Type.hs
@@ -1,8 +1,9 @@
 {-# LANGUAGE CPP #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE Rank2Types #-}
 {-# LANGUAGE LiberalTypeSynonyms #-}
-{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE FlexibleInstances #-}
 
 #ifndef MIN_VERSION_mtl
 #define MIN_VERSION_mtl(x,y,z) 1
@@ -53,15 +54,24 @@
   , (%%~)
   , (%%=)
 
-  -- ** Common Lenses
-  , _1, _2
-  , resultAt
-
   -- * Traversing and Lensing
   , Focus(..)
 
-  -- * Cloning Lenses
-  , clone
+  -- * Common Lenses
+  -- ** Tuples
+  , Field1(..)
+  , Field2(..)
+  , Field3(..)
+  , Field4(..)
+  , Field5(..)
+  , Field6(..)
+  , Field7(..)
+  , Field8(..)
+  , Field9(..)
+  -- ** Functions
+  , resultAt
+
+  -- * Lateral Composition
   , merged
   , bothLenses
 
@@ -71,12 +81,16 @@
   -- * Setting State with Passthrough
   , (<%=), (<+=), (<-=), (<*=), (<//=), (<^=), (<^^=), (<**=), (<||=), (<&&=), (<<>=)
 
+  -- * Cloning Lenses
+  , clone
+
   -- * Simplified and In-Progress
   , LensLike
   , Overloaded
   , SimpleLens
   , SimpleLensLike
   , SimpleOverloaded
+
   ) where
 
 import Control.Applicative              as Applicative
@@ -295,6 +309,7 @@
 -- Common Lenses
 ------------------------------------------------------------------------------
 
+{-
 -- | This is a lens that can change the value (and type) of the first field of
 -- a pair.
 --
@@ -322,6 +337,7 @@
 _2 :: Lens (c,a) (c,b) a b
 _2 f (c,a) = (,) c <$> f a
 {-# INLINE _2 #-}
+-}
 
 -- | This lens can be used to change the result of a function but only where
 -- the arguments match the key given.
@@ -358,6 +374,8 @@
 -- Note: This only accepts a proper 'Lens', because 'IndexedStore' lacks its
 -- (admissable) 'Applicative' instance.
 --
+-- \"Costate Comonad Coalgebra is equivalent of Java's member variable update technology for Haskell\"
+-- -- \@PLT_Borat on Twitter
 clone :: Functor f
       => LensLike (IndexedStore c d) a b c d
       -> (c -> f d) -> a -> f b
@@ -537,12 +555,253 @@
 l <<>= r = l <%= (`mappend` r)
 {-# INLINE (<<>=) #-}
 
--- These belong in Setter.
-{-
-(<.~) :: LensLike ((,)d) a b c d -> d -> a -> (d, b)
-l <.~ d = l $ \_ -> (d,d)
-{-# INLINE (<.~) #-}
+-- | Provides access to 1st field of a tuple.
+class Field1 a b c d | a -> c, b -> d, a d -> b, b c -> a where
+  -- | Access the 1st field of a tuple (and possibly change its type).
+  --
+  -- >>> import Control.Lens
+  -- >>> (1,2)^._1
+  -- 1
+  --
+  -- >>> _1 .~ "hello" $ (1,2)
+  -- ("hello",2)
+  --
+  -- This can also be used on larger tuples as well
+  --
+  -- >>> _1 +~ 41 $ (1,2,3,4,5)
+  -- (42,2,3,4,5)
+  --
+  -- @
+  -- _1 :: 'Lens' (a,b) (a',b) a a'
+  -- _1 :: 'Lens' (a,b,c) (a',b,c) a a'
+  -- _1 :: 'Lens' (a,b,c,d) (a',b,c,d) a a'
+  -- ...
+  -- _1 :: 'Lens' (a,c,d,e,f,g,h,i) (a',b,c,d,e,f,g,h,i) a a'
+  -- @
+  _1 :: Lens a b c d
 
-(<.=) :: MonadState a m => LensLike ((,)d) a a c d -> d -> m d
-(<.=) l = state (l.~)
--}
+instance Field1 (a,b) (a',b) a a' where
+  _1 k (a,b) = (\a' -> (a',b)) <$> k a
+  {-# INLINE _1 #-}
+
+instance Field1 (a,b,c) (a',b,c) a a' where
+  _1 k (a,b,c) = (\a' -> (a',b,c)) <$> k a
+  {-# INLINE _1 #-}
+
+instance Field1 (a,b,c,d) (a',b,c,d) a a' where
+  _1 k (a,b,c,d) = (\a' -> (a',b,c,d)) <$> k a
+  {-# INLINE _1 #-}
+
+instance Field1 (a,b,c,d,e) (a',b,c,d,e) a a' where
+  _1 k (a,b,c,d,e) = (\a' -> (a',b,c,d,e)) <$> k a
+  {-# INLINE _1 #-}
+
+instance Field1 (a,b,c,d,e,f) (a',b,c,d,e,f) a a' where
+  _1 k (a,b,c,d,e,f) = (\a' -> (a',b,c,d,e,f)) <$> k a
+  {-# INLINE _1 #-}
+
+instance Field1 (a,b,c,d,e,f,g) (a',b,c,d,e,f,g) a a' where
+  _1 k (a,b,c,d,e,f,g) = (\a' -> (a',b,c,d,e,f,g)) <$> k a
+  {-# INLINE _1 #-}
+
+instance Field1 (a,b,c,d,e,f,g,h) (a',b,c,d,e,f,g,h) a a' where
+  _1 k (a,b,c,d,e,f,g,h) = (\a' -> (a',b,c,d,e,f,g,h)) <$> k a
+  {-# INLINE _1 #-}
+
+instance Field1 (a,b,c,d,e,f,g,h,i) (a',b,c,d,e,f,g,h,i) a a' where
+  _1 k (a,b,c,d,e,f,g,h,i) = (\a' -> (a',b,c,d,e,f,g,h,i)) <$> k a
+  {-# INLINE _1 #-}
+
+-- | Provides access to the 2nd field of a tuple
+class Field2 a b c d | a -> c, b -> d, a d -> b, b c -> a where
+  -- | Access the 2nd field of a tuple
+  --
+  -- >>> import Control.Lens
+  -- >>> _2 .~ "hello" $ (1,(),3,4)
+  -- (1,"hello",3,4)
+  --
+  -- @
+  -- 'Control.Lens.Fold.anyOf' '_2' :: (c -> 'Bool') -> (a, c) -> 'Bool'
+  -- 'Data.Traversable.traverse' '.' '_2' :: ('Applicative' f, 'Data.Traversable.Traversable' t) => (a -> f b) -> t (c, a) -> f (t (c, b))
+  -- 'Control.Lens.Fold.foldMapOf' ('Data.Traversable.traverse' '.' '_2') :: ('Data.Traversable.Traversable' t, 'Data.Monoid.Monoid' m) => (c -> m) -> t (b, c) -> m
+  -- @
+  _2 :: Lens a b c d
+
+instance Field2 (a,b) (a,b') b b' where
+  _2 k (a,b) = (\b' -> (a,b')) <$> k b
+  {-# INLINE _2 #-}
+
+instance Field2 (a,b,c) (a,b',c) b b' where
+  _2 k (a,b,c) = (\b' -> (a,b',c)) <$> k b
+  {-# INLINE _2 #-}
+
+instance Field2 (a,b,c,d) (a,b',c,d) b b' where
+  _2 k (a,b,c,d) = (\b' -> (a,b',c,d)) <$> k b
+  {-# INLINE _2 #-}
+
+instance Field2 (a,b,c,d,e) (a,b',c,d,e) b b' where
+  _2 k (a,b,c,d,e) = (\b' -> (a,b',c,d,e)) <$> k b
+  {-# INLINE _2 #-}
+
+instance Field2 (a,b,c,d,e,f) (a,b',c,d,e,f) b b' where
+  _2 k (a,b,c,d,e,f) = (\b' -> (a,b',c,d,e,f)) <$> k b
+  {-# INLINE _2 #-}
+
+instance Field2 (a,b,c,d,e,f,g) (a,b',c,d,e,f,g) b b' where
+  _2 k (a,b,c,d,e,f,g) = (\b' -> (a,b',c,d,e,f,g)) <$> k b
+  {-# INLINE _2 #-}
+
+instance Field2 (a,b,c,d,e,f,g,h) (a,b',c,d,e,f,g,h) b b' where
+  _2 k (a,b,c,d,e,f,g,h) = (\b' -> (a,b',c,d,e,f,g,h)) <$> k b
+  {-# INLINE _2 #-}
+
+instance Field2 (a,b,c,d,e,f,g,h,i) (a,b',c,d,e,f,g,h,i) b b' where
+  _2 k (a,b,c,d,e,f,g,h,i) = (\b' -> (a,b',c,d,e,f,g,h,i)) <$> k b
+  {-# INLINE _2 #-}
+
+-- | Provides access to the 3rd field of a tuple
+class Field3 a b c d | a -> c, b -> d, a d -> b, b c -> a where
+  -- | Access the 3rd field of a tuple
+  _3 :: Lens a b c d
+
+instance Field3 (a,b,c) (a,b,c') c c' where
+  _3 k (a,b,c) = (\c' -> (a,b,c')) <$> k c
+  {-# INLINE _3 #-}
+
+instance Field3 (a,b,c,d) (a,b,c',d) c c' where
+  _3 k (a,b,c,d) = (\c' -> (a,b,c',d)) <$> k c
+  {-# INLINE _3 #-}
+
+instance Field3 (a,b,c,d,e) (a,b,c',d,e) c c' where
+  _3 k (a,b,c,d,e) = (\c' -> (a,b,c',d,e)) <$> k c
+  {-# INLINE _3 #-}
+
+instance Field3 (a,b,c,d,e,f) (a,b,c',d,e,f) c c' where
+  _3 k (a,b,c,d,e,f) = (\c' -> (a,b,c',d,e,f)) <$> k c
+  {-# INLINE _3 #-}
+
+instance Field3 (a,b,c,d,e,f,g) (a,b,c',d,e,f,g) c c' where
+  _3 k (a,b,c,d,e,f,g) = (\c' -> (a,b,c',d,e,f,g)) <$> k c
+  {-# INLINE _3 #-}
+
+instance Field3 (a,b,c,d,e,f,g,h) (a,b,c',d,e,f,g,h) c c' where
+  _3 k (a,b,c,d,e,f,g,h) = (\c' -> (a,b,c',d,e,f,g,h)) <$> k c
+  {-# INLINE _3 #-}
+
+instance Field3 (a,b,c,d,e,f,g,h,i) (a,b,c',d,e,f,g,h,i) c c' where
+  _3 k (a,b,c,d,e,f,g,h,i) = (\c' -> (a,b,c',d,e,f,g,h,i)) <$> k c
+  {-# INLINE _3 #-}
+
+-- | Provide access to the 4th field of a tuple
+class Field4 a b c d | a -> c, b -> d, a d -> b, b c -> a where
+  -- | Access the 4th field of a tuple
+  _4 :: Lens a b c d
+
+instance Field4 (a,b,c,d) (a,b,c,d') d d' where
+  _4 k (a,b,c,d) = (\d' -> (a,b,c,d')) <$> k d
+  {-# INLINE _4 #-}
+
+instance Field4 (a,b,c,d,e) (a,b,c,d',e) d d' where
+  _4 k (a,b,c,d,e) = (\d' -> (a,b,c,d',e)) <$> k d
+  {-# INLINE _4 #-}
+
+instance Field4 (a,b,c,d,e,f) (a,b,c,d',e,f) d d' where
+  _4 k (a,b,c,d,e,f) = (\d' -> (a,b,c,d',e,f)) <$> k d
+  {-# INLINE _4 #-}
+
+instance Field4 (a,b,c,d,e,f,g) (a,b,c,d',e,f,g) d d' where
+  _4 k (a,b,c,d,e,f,g) = (\d' -> (a,b,c,d',e,f,g)) <$> k d
+  {-# INLINE _4 #-}
+
+instance Field4 (a,b,c,d,e,f,g,h) (a,b,c,d',e,f,g,h) d d' where
+  _4 k (a,b,c,d,e,f,g,h) = (\d' -> (a,b,c,d',e,f,g,h)) <$> k d
+  {-# INLINE _4 #-}
+
+instance Field4 (a,b,c,d,e,f,g,h,i) (a,b,c,d',e,f,g,h,i) d d' where
+  _4 k (a,b,c,d,e,f,g,h,i) = (\d' -> (a,b,c,d',e,f,g,h,i)) <$> k d
+  {-# INLINE _4 #-}
+
+-- | Provides access to the 5th field of a tuple
+class Field5 a b c d | a -> c, b -> d, a d -> b, b c -> a where
+  -- | Access the 5th field of a tuple
+  _5 :: Lens a b c d
+
+instance Field5 (a,b,c,d,e) (a,b,c,d,e') e e' where
+  _5 k (a,b,c,d,e) = (\e' -> (a,b,c,d,e')) <$> k e
+  {-# INLINE _5 #-}
+
+instance Field5 (a,b,c,d,e,f) (a,b,c,d,e',f) e e' where
+  _5 k (a,b,c,d,e,f) = (\e' -> (a,b,c,d,e',f)) <$> k e
+  {-# INLINE _5 #-}
+
+instance Field5 (a,b,c,d,e,f,g) (a,b,c,d,e',f,g) e e' where
+  _5 k (a,b,c,d,e,f,g) = (\e' -> (a,b,c,d,e',f,g)) <$> k e
+  {-# INLINE _5 #-}
+
+instance Field5 (a,b,c,d,e,f,g,h) (a,b,c,d,e',f,g,h) e e' where
+  _5 k (a,b,c,d,e,f,g,h) = (\e' -> (a,b,c,d,e',f,g,h)) <$> k e
+  {-# INLINE _5 #-}
+
+instance Field5 (a,b,c,d,e,f,g,h,i) (a,b,c,d,e',f,g,h,i) e e' where
+  _5 k (a,b,c,d,e,f,g,h,i) = (\e' -> (a,b,c,d,e',f,g,h,i)) <$> k e
+  {-# INLINE _5 #-}
+
+-- | Provides access to the 6th element of a tuple
+class Field6 a b c d | a -> c, b -> d, a d -> b, b c -> a where
+  -- | Access the 6th field of a tuple
+  _6 :: Lens a b c d
+
+instance Field6 (a,b,c,d,e,f) (a,b,c,d,e,f') f f' where
+  _6 k (a,b,c,d,e,f) = (\f' -> (a,b,c,d,e,f')) <$> k f
+  {-# INLINE _6 #-}
+
+instance Field6 (a,b,c,d,e,f,g) (a,b,c,d,e,f',g) f f' where
+  _6 k (a,b,c,d,e,f,g) = (\f' -> (a,b,c,d,e,f',g)) <$> k f
+  {-# INLINE _6 #-}
+
+instance Field6 (a,b,c,d,e,f,g,h) (a,b,c,d,e,f',g,h) f f' where
+  _6 k (a,b,c,d,e,f,g,h) = (\f' -> (a,b,c,d,e,f',g,h)) <$> k f
+  {-# INLINE _6 #-}
+
+instance Field6 (a,b,c,d,e,f,g,h,i) (a,b,c,d,e,f',g,h,i) f f' where
+  _6 k (a,b,c,d,e,f,g,h,i) = (\f' -> (a,b,c,d,e,f',g,h,i)) <$> k f
+  {-# INLINE _6 #-}
+
+-- | Provide access to the 7th field of a tuple
+class Field7 a b c d | a -> c, b -> d, a d -> b, b c -> a where
+  -- | Access the 7th field of a tuple
+  _7 :: Lens a b c d
+
+instance Field7 (a,b,c,d,e,f,g) (a,b,c,d,e,f,g') g g' where
+  _7 k (a,b,c,d,e,f,g) = (\g' -> (a,b,c,d,e,f,g')) <$> k g
+  {-# INLINE _7 #-}
+
+instance Field7 (a,b,c,d,e,f,g,h) (a,b,c,d,e,f,g',h) g g' where
+  _7 k (a,b,c,d,e,f,g,h) = (\g' -> (a,b,c,d,e,f,g',h)) <$> k g
+  {-# INLINE _7 #-}
+
+instance Field7 (a,b,c,d,e,f,g,h,i) (a,b,c,d,e,f,g',h,i) g g' where
+  _7 k (a,b,c,d,e,f,g,h,i) = (\g' -> (a,b,c,d,e,f,g',h,i)) <$> k g
+  {-# INLINE _7 #-}
+
+-- | Provide access to the 8th field of a tuple
+class Field8 a b c d | a -> c, b -> d, a d -> b, b c -> a where
+  -- | Access the 8th field of a tuple
+  _8 :: Lens a b c d
+
+instance Field8 (a,b,c,d,e,f,g,h) (a,b,c,d,e,f,g,h') h h' where
+  _8 k (a,b,c,d,e,f,g,h) = (\h' -> (a,b,c,d,e,f,g,h')) <$> k h
+  {-# INLINE _8 #-}
+
+instance Field8 (a,b,c,d,e,f,g,h,i) (a,b,c,d,e,f,g,h',i) h h' where
+  _8 k (a,b,c,d,e,f,g,h,i) = (\h' -> (a,b,c,d,e,f,g,h',i)) <$> k h
+  {-# INLINE _8 #-}
+
+-- | Provides access to the 9th field of a tuple
+class Field9 a b c d | a -> c, b -> d, a d -> b, b c -> a where
+  -- | Access the 9th field of a tuple
+  _9 :: Lens a b c d
+
+instance Field9 (a,b,c,d,e,f,g,h,i) (a,b,c,d,e,f,g,h,i') i i' where
+  _9 k (a,b,c,d,e,f,g,h,i) = (\i' -> (a,b,c,d,e,f,g,h,i')) <$> k i
+  {-# INLINE _9 #-}
