diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,11 @@
+# 0.1.1.0
+
+* Added `makeLensesFor` (and `lensRulesFor`).
+
+# 0.1.0.1
+
+* Wrote a bit of documentation.
+
+# 0.1.0.0
+
+Initial release.
diff --git a/microlens-th.cabal b/microlens-th.cabal
--- a/microlens-th.cabal
+++ b/microlens-th.cabal
@@ -1,6 +1,6 @@
 name:                microlens-th
-version:             0.1.0.0
-synopsis:            Automatic generation of record lenses for 'microlens'.
+version:             0.1.1.0
+synopsis:            Automatic generation of record lenses for microlens
 description:
   This package lets you automatically generate lenses for data types; code
   was extracted from the lens package, and therefore generated lenses are
@@ -12,10 +12,10 @@
 maintainer:          Artyom <yom@artyom.me>
 homepage:            http://github.com/aelve/microlens
 bug-reports:         http://github.com/aelve/microlens/issues
--- copyright:           
 category:            Data, Lenses
 build-type:          Simple
--- extra-source-files:  README.md
+extra-source-files:
+  CHANGELOG.md
 cabal-version:       >=1.10
 
 source-repository head
diff --git a/src/Lens/Micro/TH.hs b/src/Lens/Micro/TH.hs
--- a/src/Lens/Micro/TH.hs
+++ b/src/Lens/Micro/TH.hs
@@ -1,8 +1,8 @@
 {-# LANGUAGE
-      CPP
-    , TemplateHaskell
-    , RankNTypes
-    , FlexibleContexts
+CPP,
+TemplateHaskell,
+RankNTypes,
+FlexibleContexts
   #-}
 
 #ifndef MIN_VERSION_template_haskell
@@ -18,14 +18,16 @@
   -- $compatnote
   Getter,
   Fold,
-  -- * Make lenses
+  -- * Making lenses
   makeLenses,
+  makeLensesFor,
   makeLensesWith,
   makeFields,
   -- * Default lens rules
   LensRules,
   DefName(..),
   lensRules,
+  lensRulesFor,
   defaultFieldRules,
   camelCaseFields,
   -- * Configuring lens rules
@@ -68,9 +70,7 @@
 type Getter s a = forall r. Getting r s a
 type Fold s a = forall r. Applicative (Const r) => Getting r s a
 
---
--- Lens functions which would've been in Lens.Micro if it wasn't "micro".
---
+-- Lens functions which would've been in Lens.Micro if it wasn't “micro”
 
 elemOf :: Eq a => Getting (Endo [a]) s a -> a -> s -> Bool
 elemOf l x = elem x . toListOf l
@@ -85,16 +85,10 @@
 _ForallT f (ForallT a b c) = (\(x, y, z) -> ForallT x y z) <$> f (a, b, c)
 _ForallT _ other = pure other
 
-_head :: Traversal' [a] a
-_head f (a:as) = (:as) <$> f a
-_head _ []     = pure []
-
 coerce :: Const r a -> Const r b
 coerce = Const . getConst
 
---
--- Utilities.
---
+-- Utilities
 
 -- | Modify element at some index in a list.
 setIx :: Int -> a -> [a] -> [a]
@@ -119,17 +113,224 @@
 fromSet f x = Map.fromDistinctAscList [ (k,f k) | k <- Set.toAscList x ]
 #endif
 
---
+overHead :: (a -> a) -> [a] -> [a]
+overHead _ []     = []
+overHead f (x:xs) = f x : xs
+
 -- Control.Lens.TH
---
 
+{- |
+Generate lenses for a data type or a newtype.
+
+To use, you have to enable Template Haskell:
+
+@
+{-# LANGUAGE TemplateHaskell #-}
+@
+
+Then, after declaring the datatype (let's say @Foo@), add @makeLenses ''Foo@
+on a separate line:
+
+@
+data Foo = Foo {
+  _x :: Int,
+  _y :: Bool }
+
+makeLenses ''Foo
+@
+
+This would generate the following lenses, which can be used to access the
+fields of @Foo@:
+
+@
+x :: 'Lens'' Foo Int
+x f foo = (\\x' -> f {_x = x'}) '<$>' f (_x foo)
+
+y :: 'Lens'' Foo Bool
+y f foo = (\\y' -> f {_y = y'}) '<$>' f (_y foo)
+@
+
+If you don't want a lens to be generated for some field, don't prefix it with
+an @_@.
+
+When the data type has type parameters, it's possible for a lens to do a
+polymorphic update – i.e. change the type of the thing along with changing
+the type of the field. For instance, with this type:
+
+@
+data Foo a = Foo {
+  _x :: a,
+  _y :: Bool }
+@
+
+the following lenses would be generated:
+
+@
+x :: 'Lens' (Foo a) (Foo b) a b
+y :: 'Lens'' (Foo a) Bool
+@
+
+However, when there are several fields using the same type parameter,
+type-changing updates are no longer possible:
+
+@
+data Foo a = Foo {
+  _x :: a,
+  _y :: a }
+@
+
+generates
+
+@
+x :: 'Lens'' (Foo a) a
+y :: 'Lens'' (Foo a) a
+@
+
+Next thing. When the type has several constructors, some of fields may not be
+/always/ present – for those, a 'Traversal' is generated instead. For
+instance, in this example @y@ can be present or absent:
+
+@
+data FooBar
+  = Foo { _x :: Int, _y :: Bool }
+  | Bar { _x :: Int }
+@
+
+and the following accessors would be generated:
+
+@
+x :: 'Lens'' FooBar Int
+y :: 'Traversal'' FooBar Bool
+@
+
+So, to get @_y@, you'd have to either use ('^?') if you're not sure it's
+there, or ('^?!') if you're absolutely sure (and if you're wrong, you'll get
+an exception). Setting and updating @_y@ can be done as usual.
+-}
 makeLenses :: Name -> DecsQ
 makeLenses = makeFieldOptics lensRules
 
--- | Build lenses with a custom configuration.
+{- |
+Like 'makeLenses', but lets you choose your own names for lenses:
+
+@
+data Foo = Foo {foo :: Int, bar :: Bool}
+
+'makeLensesFor' [(\"foo\", \"fooLens\"), (\"bar\", \"_bar\")] ''Foo
+@
+
+would create lenses called @fooLens@ and @_bar@. This is useful, for instance,
+when you don't want to prefix your fields with underscores and want to prefix
+/lenses/ with underscores instead.
+
+If you give the same name to different fields, it will generate a 'Traversal'
+instead:
+
+@
+data Foo = Foo {slot1, slot2, slot3 :: Int}
+
+'makeLensesFor' [(\"slot1\", \"slots\"),
+                 (\"slot2\", \"slots\"),
+                 (\"slot3\", \"slots\")] ''Foo
+@
+-}
+makeLensesFor :: [(String, String)] -> Name -> DecsQ
+makeLensesFor fields = makeFieldOptics (lensRulesFor fields)
+
+{- |
+Generate lenses with custom parameters.
+
+This function lets you customise generated lenses; to see what exactly can be
+changed, look at 'LensRules'. 'makeLenses' is implemented with
+'makeLensesWith' – it uses the 'lensRules' configuration (which you can build
+upon – see the “Configuring lens rules” section).
+
+Here's an example of generating lenses that would use lazy patterns:
+
+@
+data Foo = Foo {_x, _y :: Int}
+
+'makeLensesWith' ('lensRules' '&' 'generateLazyPatterns' '.~' True) ''Foo
+@
+
+When there are several modifications to the rules, the code looks nicer when
+you use 'flip':
+
+@
+'flip' 'makeLensesWith' ''Foo $
+  'lensRules'
+    '&' 'generateLazyPatterns' '.~' True
+    '&' 'generateSignatures'   '.~' False
+@
+-}
 makeLensesWith :: LensRules -> Name -> DecsQ
 makeLensesWith = makeFieldOptics
 
+{- |
+Generate overloaded lenses.
+
+This lets you deal with several data types having same fields. For instance,
+let's say you have @Foo@ and @Bar@, and both have a field named @x@. To
+avoid those fields clashing, you would have to use prefixes:
+
+@
+data Foo a = Foo {
+  fooX :: Int,
+  fooY :: a }
+
+data Bar = Bar {
+  barX :: Char }
+@
+
+However, if you use 'makeFields' on both @Foo@ and @Bar@ now, it would
+generate lenses called @x@ and @y@ – and @x@ would be able to access both
+@fooX@ and @barX@! This is done by generating a separate class for each
+field, and making relevant types instances of that class:
+
+@
+class HasX s a | s -> a where
+  x :: 'Lens'' s a
+
+instance HasX (Foo a) Int where
+  x :: 'Lens'' (Foo a) Int
+  x = ...
+
+instance HasX Bar Char where
+  x :: 'Lens'' Bar Char
+  x = ...
+
+
+class HasY s a | s -> a where
+  y :: 'Lens'' s a
+
+instance HasY (Foo a) a where
+  y :: 'Lens'' (Foo a) a
+  y = ...
+@
+
+(There's a minor drawback, tho: you can't perform type-changing updates with
+these lenses.)
+
+If you only want to make lenses for some fields, you can prefix them with
+underscores – the rest would be untouched. If no fields are prefixed with
+underscores, lenses would be created for all fields.
+
+The prefix must be the same as the name of the name of the data type (/not/
+the constructor).
+
+If you want to use 'makeFields' on types declared in different modules, you
+can do it, but then you would have to export the @Has*@ classes from one of
+the modules – 'makeFields' creates a class if it's not in scope yet, so the
+class must be in scope or else there would be duplicate classes and you would
+get an “Ambiguous occurrence” error.
+
+Finally, 'makeFields' is implemented as @'makeLenses' 'camelCaseFields'@, so
+you can build on 'camelCaseFields' if you want to customise behavior of
+'makeFields'.
+-}
+makeFields :: Name -> DecsQ
+makeFields = makeFieldOptics camelCaseFields
+
 -- | Generate "simple" optics even when type-changing optics are possible.
 -- (e.g. 'Lens'' instead of 'Lens')
 simpleLenses :: Lens' LensRules Bool
@@ -152,19 +353,35 @@
 generateUpdateableOptics f r =
   fmap (\x -> r { _allowUpdates = x}) (f (_allowUpdates r))
 
--- | Generate optics using lazy pattern matches. This can
--- allow fields of an undefined value to be initialized with lenses,
--- and is the default behavior.
---
--- The downside of this flag is that it can lead to space-leaks and
--- code-size/compile-time increases when generated for large records.
---
--- When using lazy optics the strict optic can be recovered by composing
--- with '$!'
---
--- @
--- strictOptic = ($!) . lazyOptic
--- @
+{- |
+Generate optics using lazy pattern matches. This can allow fields of an
+undefined value to be initialized with lenses:
+
+@
+data Foo = Foo {_x :: Int, _y :: Bool}
+  deriving Show
+
+'makeLensesWith' ('lensRules' '&' 'generateLazyPatterns' '.~' True) ''Foo
+@
+
+@
+> 'undefined' '&' x '.~' 8 '&' y '.~' True
+Foo {_x = 8, _y = True}
+@
+
+(Without 'generateLazyPatterns', the result would be just 'undefined'.)
+
+The downside of this flag is that it can lead to space-leaks and
+code-size\/compile-time increases when generated for large records. By
+default this flag is turned off, and strict optics are generated.
+
+When you have a lazy optic, you can get a strict optic from it by composing
+with ('$!'):
+
+@
+strictOptic = ('$!') . lazyOptic
+@
+-}
 generateLazyPatterns :: Lens' LensRules Bool
 generateLazyPatterns f r =
   fmap (\x -> r { _lazyPatterns = x}) (f (_lazyPatterns r))
@@ -206,6 +423,16 @@
          _        -> []
   }
 
+-- | Used in 'makeLensesFor'.
+lensRulesFor ::
+  [(String, String)] {- ^ [(Field Name, Lens Name)] -} ->
+  LensRules
+lensRulesFor fields = lensRules & lensField .~ mkNameLookup fields
+
+mkNameLookup :: [(String,String)] -> Name -> [Name] -> Name -> [DefName]
+mkNameLookup kvs _ _ field =
+  [ TopName (mkName v) | (k,v) <- kvs, k == nameBase field]
+
 camelCaseFields :: LensRules
 camelCaseFields = defaultFieldRules
 
@@ -218,16 +445,13 @@
   return (MethodName (mkName cls) (mkName method))
 
   where
-  expectedPrefix = optUnderscore ++ over _head toLower (nameBase tyName)
+  expectedPrefix = optUnderscore ++ overHead toLower (nameBase tyName)
 
   optUnderscore  = ['_' | any (isPrefixOf "_" . nameBase) fields ]
 
   computeMethod (x:xs) | isUpper x = Just (toLower x : xs)
   computeMethod _                  = Nothing
 
-makeFields :: Name -> DecsQ
-makeFields = makeFieldOptics camelCaseFields
-
 defaultFieldRules :: LensRules
 defaultFieldRules = LensRules
   { _simpleLenses    = True
@@ -240,9 +464,7 @@
   , _fieldToDef      = camelCaseNamer
   }
 
---
 -- Language.Haskell.TH.Lens
---
 
 -- | Has a 'Name'
 class HasName t where
@@ -319,9 +541,7 @@
 substTypeVars :: HasTypeVars t => Map Name Name -> t -> t
 substTypeVars m = over typeVars $ \n -> fromMaybe n (Map.lookup n m)
 
---
 -- FieldTH.hs
---
 
 ------------------------------------------------------------------------
 -- Field generation entry point
@@ -556,84 +776,7 @@
 
   clauses = makeFieldClauses rules opticType cons
 
-{-
-
 ------------------------------------------------------------------------
--- Classy class generator
-------------------------------------------------------------------------
-
-
-makeClassyDriver ::
-  LensRules ->
-  Name ->
-  Name ->
-  Type {- ^ Outer 's' type -} ->
-  [(DefName, (OpticType, OpticStab, [(Name, Int, [Int])]))] ->
-  DecsQ
-makeClassyDriver rules className methodName s defs = sequenceA (cls ++ inst)
-
-  where
-  cls | _generateClasses rules = [makeClassyClass className methodName s defs]
-      | otherwise = []
-
-  inst = [makeClassyInstance rules className methodName s defs]
-
-
-makeClassyClass ::
-  Name ->
-  Name ->
-  Type {- ^ Outer 's' type -} ->
-  [(DefName, (OpticType, OpticStab, [(Name, Int, [Int])]))] ->
-  DecQ
-makeClassyClass className methodName s defs = do
-  let ss   = map (stabToS . view (_2 . _2)) defs
-  (sub,s') <- unifyTypes (s : ss)
-  c <- newName "c"
-  let vars = toListOf typeVars s'
-      fd   | null vars = []
-           | otherwise = [FunDep [c] vars]
-
-
-  classD (cxt[]) className (map PlainTV (c:vars)) fd
-    $ sigD methodName (return (''Lens' `conAppsT` [VarT c, s']))
-    : concat
-      [ [sigD defName (return ty)
-        ,valD (varP defName) (normalB body) []
-        ] ++
-        inlinePragma defName
-      | (TopName defName, (_, stab, _)) <- defs
-      , let body = appsE [varE '(.), varE methodName, varE defName]
-      , let ty   = quantifyType' (Set.fromList (c:vars))
-                                 (stabToContext stab)
-                 $ stabToOptic stab `conAppsT`
-                       [VarT c, applyTypeSubst sub (stabToA stab)]
-      ]
-
-
-makeClassyInstance ::
-  LensRules ->
-  Name ->
-  Name ->
-  Type {- ^ Outer 's' type -} ->
-  [(DefName, (OpticType, OpticStab, [(Name, Int, [Int])]))] ->
-  DecQ
-makeClassyInstance rules className methodName s defs = do
-  methodss <- traverse (makeFieldOptic rules') defs
-
-  instanceD (cxt[]) (return instanceHead)
-    $ valD (varP methodName) (normalB (varE 'id)) []
-    : map return (concat methodss)
-
-  where
-  instanceHead = className `conAppsT` (s : map VarT vars)
-  vars         = toListOf typeVars s
-  rules'       = rules { _generateSigs    = False
-                       , _generateClasses = False
-                       }
-
--}
-
-------------------------------------------------------------------------
 -- Field class generation
 ------------------------------------------------------------------------
 
@@ -734,18 +877,6 @@
             (normalB body)
             []
 
-{-
-
--- | Build a clause that constructs an Iso
-makeIsoClause :: Name -> ClauseQ
-makeIsoClause conName = clause [] (normalB (appsE [varE 'iso, destruct, construct])) []
-  where
-  destruct  = do x <- newName "x"
-                 lam1E (conP conName [varP x]) (varE x)
-
-  construct = conE conName
--}
-
 ------------------------------------------------------------------------
 -- Unification logic
 ------------------------------------------------------------------------
@@ -816,6 +947,13 @@
 -- Field generation parameters
 ------------------------------------------------------------------------
 
+{- |
+Rules used to generate lenses. You can't create them from scratch, but you
+can customise already existing ones with lenses in the “Configuring lens
+rules” section.
+
+For an example, see 'makeLensesWith'.
+-}
 data LensRules = LensRules
   { _simpleLenses    :: Bool
   , _generateSigs    :: Bool
@@ -829,10 +967,12 @@
        -- type name to class name and top method
   }
 
--- | Name to give to generated field optics.
+{- |
+Name to give to a generated lens.
+-}
 data DefName
-  = TopName Name -- ^ Simple top-level definiton name
-  | MethodName Name Name -- ^ makeFields-style class name and method name
+  = TopName Name          -- ^ Simple top-level definiton name
+  | MethodName Name Name  -- ^ 'makeFields'-style class name and method name
   deriving (Show, Eq, Ord)
 
 ------------------------------------------------------------------------
@@ -884,9 +1024,7 @@
 
 #endif
 
---
 -- Control.Lens.Internal.TH
---
 
 -- | Apply arguments to a type constructor.
 conAppsT :: Name -> [Type] -> Type
