diff --git a/one-liner.cabal b/one-liner.cabal
--- a/one-liner.cabal
+++ b/one-liner.cabal
@@ -1,7 +1,14 @@
 Name:                 one-liner
-Version:              0.2.2
+Version:              0.3
 Synopsis:             Constraint-based generics
 Description:          Write short and concise generic instances of type classes.
+                      .
+                      There are two separate parts: @Generics.OneLiner@ is for
+                      writing generic functions using @GHC.Generics@.
+                      The other modules show how to implement these same generic
+                      functions with a traversal-style generics type class,
+                      without the use of an intermediate generic representation
+                      type.
 Homepage:             https://github.com/sjoerdvisscher/one-liner
 Bug-reports:          https://github.com/sjoerdvisscher/one-liner/issues
 License:              BSD3
@@ -17,16 +24,17 @@
 
 Library
   HS-Source-Dirs:  src
-  
+
   Exposed-modules:
+    Generics.OneLiner
     Generics.OneLiner.ADT
     Generics.OneLiner.ADT1
     Generics.OneLiner.Functions
     Generics.OneLiner.Functions1
     Generics.OneLiner.Info
-  
+
   Build-depends:
-      base         >= 4.5 && < 5 
+      base         >= 4.5 && < 5
     , transformers >= 0.3 && < 0.5
     , ghc-prim
 
diff --git a/src/Generics/OneLiner.hs b/src/Generics/OneLiner.hs
new file mode 100644
--- /dev/null
+++ b/src/Generics/OneLiner.hs
@@ -0,0 +1,236 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Generics.OneLiner
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  sjoerd@w3future.com
+-- Stability   :  experimental
+-- Portability :  non-portable
+--
+-- This module is for writing generic functions on algebraic data types
+-- of kind @*@. These data types must be an instance of the `Generic` type
+-- class, which can be derived.
+--
+-----------------------------------------------------------------------------
+{-# LANGUAGE
+    RankNTypes
+  , TypeFamilies
+  , TypeOperators
+  , ConstraintKinds
+  , FlexibleContexts
+  , FlexibleInstances
+  , DefaultSignatures
+  , ScopedTypeVariables
+  #-}
+module Generics.OneLiner (
+  -- * Producing values
+  create, createA, ctorIndex,
+  -- * Traversing values
+  gmap, gfoldMap, gtraverse,
+  -- * Combining values
+  gzipWith, mzipWith, zipWithA,
+  -- * Single constructor functions
+  op0, op1, op2,
+  -- * Types
+  ADT, ADTRecord, Constraints, For
+) where
+
+import GHC.Generics
+import GHC.Prim (Constraint)
+import Control.Applicative
+import Data.Functor.Identity
+import Data.Monoid
+
+-- | Collect the constraint requirements for an instance for `t` of class `c`.
+type family Constraints (t :: * -> *) (c :: * -> Constraint) :: Constraint
+type instance Constraints V1 c = ()
+type instance Constraints U1 c = ()
+type instance Constraints (f :+: g) c = (Constraints f c, Constraints g c)
+type instance Constraints (f :*: g) c = (Constraints f c, Constraints g c)
+-- | This is the only instance where actual requirements are generated.
+type instance Constraints (K1 i v) c = c v
+type instance Constraints (M1 i t f) c = Constraints f c
+
+class ADT' (t :: * -> *) where
+  ctorIndex' :: t x -> Int
+  ctorIndex' _ = 0
+  ctorCount :: proxy (t x) -> Int
+  ctorCount _ = 1
+  f0 :: (Constraints t c, Applicative f)
+     => for c -> (forall s. c s => f s) -> [f (t ())]
+  f1 :: (Constraints t c, Applicative f)
+     => for c -> (forall s. c s => s -> f s) -> t x -> f (t x)
+  f2 :: (Constraints t c, Applicative f)
+     => for c -> (forall s. c s => s -> s -> f s) -> t x -> t x -> Maybe (f (t x))
+
+instance ADT' V1 where
+  ctorCount _ = 0
+  f0 _ _ = []
+  f1 _ _ = pure
+  f2 _ _ _ = Just . pure
+
+instance (ADT' f, ADT' g) => ADT' (f :+: g) where
+  ctorIndex' (L1 l) = ctorIndex' l
+  ctorIndex' (R1 r) = ctorCount (undefined :: [f ()]) + ctorIndex' r
+  ctorCount _ = ctorCount (undefined :: [f ()]) + ctorCount (undefined :: [g ()])
+  f0 for f = map (fmap L1) (f0 for f) ++ map (fmap R1) (f0 for f)
+  f1 for f (L1 l) = L1 <$> f1 for f l
+  f1 for f (R1 r) = R1 <$> f1 for f r
+  f2 for f (L1 a) (L1 b) = fmap (fmap L1) (f2 for f a b)
+  f2 for f (R1 a) (R1 b) = fmap (fmap R1) (f2 for f a b)
+  f2 _ _ _ _ = Nothing
+
+instance ADT' U1 where
+  f0 _ _ = [pure U1]
+  f1 _ _ = pure
+  f2 _ _ _ = Just . pure
+
+instance (ADT' f, ADT' g) => ADT' (f :*: g) where
+  f0 for f = [(:*:) <$> head (f0 for f) <*> head (f0 for f)]
+  f1 for f (l :*: r) = (:*:) <$> f1 for f l <*> f1 for f r
+  f2 for f (al :*: ar) (bl :*: br) = liftA2 (:*:) <$> f2 for f al bl <*> f2 for f ar br
+
+instance ADT' (K1 i v) where
+  f0 _ f = [K1 <$> f]
+  f1 _ f (K1 v) = K1 <$> f v
+  f2 _ f (K1 l) (K1 r) = Just $ K1 <$> f l r
+
+instance ADT' f => ADT' (M1 i t f) where
+  ctorIndex' = ctorIndex' . unM1
+  ctorCount _ = ctorCount (undefined :: [M1 i t f ()])
+  f0 for f = map (fmap M1) (f0 for f)
+  f1 for f = fmap M1 . f1 for f . unM1
+  f2 for f (M1 l) (M1 r) = fmap (fmap M1) (f2 for f l r)
+
+
+class ADTRecord' (f :: * -> *) where
+instance ADTRecord' U1
+instance ADTRecord' (f :*: g)
+instance ADTRecord' (K1 i v)
+instance ADTRecord' f => ADTRecord' (M1 i t f)
+instance ADTRecord' f => ADTRecord' (V1 :+: f)
+instance ADTRecord' f => ADTRecord' (f :+: V1)
+
+
+-- | `ADT` is a constraint type synonym. The `Generic` instance can be derived,
+-- and any generic representation will be an instance of `ADT'`.
+type ADT t = (Generic t, ADT' (Rep t))
+
+-- | `ADTRecord` is a constraint type synonym. An instance is an `ADT` with exactly one constructor.
+type ADTRecord t = (ADT t, ADTRecord' (Rep t))
+
+-- | Tell the compiler which class we want to use in the traversal. Should be used like this:
+--
+-- > (For :: For Show)
+--
+-- Where @Show@ can be any class.
+data For (c :: * -> Constraint) = For
+
+-- | Create a value (one for each constructor), given how to construct the components.
+--
+-- @
+-- `minBound` = `head` `$` `create` (`For` :: `For` `Bounded`) `minBound`
+-- `maxBound` = `last` `$` `create` (`For` :: `For` `Bounded`) `maxBound`
+-- @
+create :: (ADT t, Constraints (Rep t) c)
+       => for c -> (forall s. c s => s) -> [t]
+create for f = map runIdentity (createA for (Identity f))
+
+-- | Create a value (one for each constructor), given how to construct the components, under an applicative effect.
+--
+-- Here's how to implement `get` from the `binary` package:
+--
+-- @
+-- get = getWord8 `>>=` \\ix -> `createA` (`For` :: `For` Binary) get `!!` `fromEnum` ix
+-- @
+createA :: (ADT t, Constraints (Rep t) c, Applicative f)
+        => for c -> (forall s. c s => f s) -> [f t]
+createA for f = map (fmap to) (f0 for f)
+
+-- | Get the index in the lists returned by `create` and `createA` of the constructor of the given value.
+--
+-- For example, this is the implementation of `put` that generates the binary data that
+-- the above implentation of `get` expects:
+--
+-- @
+-- `put` t = `putWord8` (`toEnum` (`ctorIndex` t)) `<>` `gfoldMap` (`For` :: `For` `Binary`) `put` t
+-- @
+--
+-- /Note that this assumes a straightforward `Monoid` instance of `Put` which `binary` unfortunately does not provide./
+ctorIndex :: ADT t => t -> Int
+ctorIndex = ctorIndex' . from
+
+-- | Map over a structure, updating each component.
+gmap :: (ADT t, Constraints (Rep t) c)
+     => for c -> (forall s. c s => s -> s) -> t -> t
+gmap for f = runIdentity . gtraverse for (Identity . f)
+
+-- | Map each component of a structure to a monoid, and combine the results.
+--
+-- If you have a class `Size`, which measures the size of a structure, then this could be the default implementation:
+--
+-- @
+-- size = `succ` `.` `getSum` `.` `gfoldMap` (`For` :: `For` Size) (`Sum` `.` size)
+-- @
+gfoldMap :: (ADT t, Constraints (Rep t) c, Monoid m)
+         => for c -> (forall s. c s => s -> m) -> t -> m
+gfoldMap for f = getConst . gtraverse for (Const . f)
+
+-- | Map each component of a structure to an action, evaluate these actions from left to right, and collect the results.
+gtraverse :: (ADT t, Constraints (Rep t) c, Applicative f)
+          => for c -> (forall s. c s => s -> f s) -> t -> f t
+gtraverse for f = fmap to . f1 for f . from
+
+-- | Combine two values by combining each component of the structures with the given function.
+-- Returns `Nothing` if the constructors don't match.
+gzipWith :: (ADT t, Constraints (Rep t) c)
+         => for c -> (forall s. c s => s -> s -> s) -> t -> t -> Maybe t
+gzipWith for f l r = runIdentity <$> zipWithA for (\x y -> Identity (f x y)) l r
+
+-- | Combine two values by combining each component of the structures to a monoid, and combine the results.
+-- Returns `mempty` if the constructors don't match.
+--
+-- @
+-- `compare` s t = `compare` (`ctorIndex` s) (`ctorIndex` t) `<>` `mzipWith` (`For` :: `For` `Ord`) `compare` s t
+-- @
+mzipWith :: (ADT t, Constraints (Rep t) c, Monoid m)
+         => for c -> (forall s. c s => s -> s -> m) -> t -> t -> m
+mzipWith for f l r = maybe mempty getConst $ zipWithA for (\x y -> Const (f x y)) l r
+
+-- | Combine two values by combining each component of the structures with the given function, under an applicative effect.
+-- Returns `Nothing` if the constructors don't match.
+zipWithA :: (ADT t, Constraints (Rep t) c, Applicative f)
+         => for c -> (forall s. c s => s -> s -> f s) -> t -> t -> Maybe (f t)
+zipWithA for f l r = fmap (fmap to) (f2 for f (from l) (from r))
+
+-- | Implement a nullary operator by calling the operator for each component.
+--
+-- @
+-- `mempty` = `op0` (`For` :: `For` `Monoid`) `mempty`
+-- `fromInteger` i = `op0` (`For` :: `For` `Num`) (`fromInteger` i)
+-- @
+op0 :: (ADTRecord t, Constraints (Rep t) c)
+    => for c -> (forall s. c s => s) -> t
+op0 for f = head $ create for f
+
+-- | Implement a unary operator by calling the operator on the components.
+-- This is here for consistency, it is the same as `gmap`.
+--
+-- @
+-- `negate` = `op1` (`For` :: `For` `Num`) `negate`
+-- @
+op1 :: (ADTRecord t, Constraints (Rep t) c)
+     => for c -> (forall s. c s => s -> s) -> t -> t
+op1 = gmap
+
+-- | Implement a binary operator by calling the operator on the components.
+--
+-- @
+-- `mappend` = `op2` (`For` :: `For` `Monoid`) `mappend`
+-- (`+`) = `op2` (`For` :: `For` `Num`) (`+`)
+-- @
+op2 :: (ADTRecord t, Constraints (Rep t) c)
+    => for c -> (forall s. c s => s -> s -> s) -> t -> t -> t
+op2 for f l r = case gzipWith for f l r of
+  Just t -> t
+  Nothing -> error "op2: constructor mismatch should not be possible for ADTRecord"
diff --git a/src/Generics/OneLiner/ADT.hs b/src/Generics/OneLiner/ADT.hs
--- a/src/Generics/OneLiner/ADT.hs
+++ b/src/Generics/OneLiner/ADT.hs
@@ -1,16 +1,15 @@
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Generics.OneLiner.ADT
--- Copyright   :  (c) Sjoerd Visscher 2012
 -- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  sjoerd@w3future.com
 -- Stability   :  experimental
 -- Portability :  non-portable
 --
--- This module is for writing generic functions on algebraic data types 
+-- This module is for writing generic functions on algebraic data types
 -- of kind @*@. These data types must be an instance of the `ADT` type class.
--- 
+--
 -- Here's an example how to write such an instance for this data type:
 --
 -- @
@@ -24,7 +23,7 @@
 --   `ctorInfo` _ 0 = `ctor` \"A\"
 --   `ctorInfo` _ 1 = `ctor` \"B\"
 --   type `Constraints` (T a) c = (c Int, c a, c (T a))
---   `buildsRecA` `For` sub rec = 
+--   `buildsRecA` _ sub rec =
 --     [ A `<$>` sub (`FieldInfo` (\\(A i _) -> i)) `<*>` sub (`FieldInfo` (\\(A _ a) -> a))
 --     , B `<$>` sub (`FieldInfo` (\\(B a _) -> a)) `<*>` rec (`FieldInfo` (\\(B _ t) -> t))
 --     ]
@@ -34,11 +33,11 @@
 --
 -- @
 -- eqADT :: (`ADT` t, `Constraints` t `Eq`) => t -> t -> `Bool`
--- eqADT s t = `ctorIndex` s == `ctorIndex` t `&&` 
+-- eqADT s t = `ctorIndex` s == `ctorIndex` t `&&`
 --   `getAll` (`mbuilds` (`For` :: `For` `Eq`) (\\fld -> `All` $ s `!` fld `==` t `!` fld) \``at`\` s)
 -- @
 -----------------------------------------------------------------------------
-{-# LANGUAGE 
+{-# LANGUAGE
     RankNTypes
   , TypeFamilies
   , ConstraintKinds
@@ -47,12 +46,12 @@
   , ScopedTypeVariables
   #-}
 module Generics.OneLiner.ADT (
-  
+
     -- * Re-exports
     module Generics.OneLiner.Info
   , Constraint
     -- | The kind of constraints
-    
+
     -- * The @ADT@ type class
   , ADT(..)
   , ADTRecord(..)
@@ -61,7 +60,7 @@
     -- * Helper functions
   , (!)
   , at
-  
+
     -- * Derived traversal schemes
   , builds
   , mbuilds
@@ -74,9 +73,9 @@
   , op0
   , op1
   , op2
-  
+
   ) where
-  
+
 import Generics.OneLiner.Info
 
 import GHC.Prim (Constraint)
@@ -95,96 +94,96 @@
 -- Where @Show@ can be any class.
 data For (c :: * -> Constraint) = For
 
--- | Type class for algebraic data types of kind @*@. Minimal implementation: `ctorIndex` and either `buildsA`
+-- | Type class for algebraic data types of kind @*@. Implement either `buildsA`
 -- if the type @t@ is not recursive, or `buildsRecA` if the type @t@ is recursive.
 class ADT t where
 
   -- | Gives the index of the constructor of the given value in the list returned by `buildsA` and `buildsRecA`.
   ctorIndex :: t -> Int
   ctorIndex _ = 0
-  
+
   -- | @ctorInfo n@ gives constructor information, f.e. its name, for the @n@th constructor.
   --   The first argument is a dummy argument and can be @(undefined :: t)@.
   ctorInfo :: t -> Int -> CtorInfo
 
-  -- | The constraints needed to run `buildsA` and `buildsRecA`. 
+  -- | The constraints needed to run `buildsA` and `buildsRecA`.
   -- It should be a list of all the types of the subcomponents of @t@, each applied to @c@.
   type Constraints t (c :: * -> Constraint) :: Constraint
-  
+
   buildsA :: (Constraints t c, Applicative f)
-          => For c -- ^ Witness for the constraint @c@.
+          => for c -- ^ Witness for the constraint @c@.
           -> (forall s. c s => FieldInfo (t -> s) -> f s) -- ^ This function should return a value
-             -- for each subcomponent of @t@, wrapped in an applicative functor @f@. It is given 
-             -- information about the field, which contains a projector function to get the subcomponent 
+             -- for each subcomponent of @t@, wrapped in an applicative functor @f@. It is given
+             -- information about the field, which contains a projector function to get the subcomponent
              -- from a value of type @t@. The type of the subcomponent is an instance of class @c@.
-          -> [f t] -- ^ A list of results, one for each constructor of type @t@. Each element is the 
-             -- result of applicatively applying the constructor to the results of the given function 
+          -> [f t] -- ^ A list of results, one for each constructor of type @t@. Each element is the
+             -- result of applicatively applying the constructor to the results of the given function
              -- for each field of the constructor.
-  
-  default buildsA :: (c t, Constraints t c, Applicative f) 
-                  => For c -> (forall s. c s => FieldInfo (t -> s) -> f s) -> [f t]
+
+  default buildsA :: (c t, Constraints t c, Applicative f)
+                  => for c -> (forall s. c s => FieldInfo (t -> s) -> f s) -> [f t]
   buildsA for f = buildsRecA for f f
-  
-  buildsRecA :: (Constraints t c, Applicative f) 
-             => For c -- ^ Witness for the constraint @c@.
+
+  buildsRecA :: (Constraints t c, Applicative f)
+             => for c -- ^ Witness for the constraint @c@.
              -> (forall s. c s => FieldInfo (t -> s) -> f s) -- ^ This function should return a value
-                -- for each subcomponent of @t@, wrapped in an applicative functor @f@. It is given 
-                -- information about the field, which contains a projector function to get the subcomponent 
+                -- for each subcomponent of @t@, wrapped in an applicative functor @f@. It is given
+                -- information about the field, which contains a projector function to get the subcomponent
                 -- from a value of type @t@. The type of the subcomponent is an instance of class @c@.
              -> (FieldInfo (t -> t) -> f t) -- ^ This function should return a value
                 -- for each subcomponent of @t@ that is itself of type @t@.
-             -> [f t] -- ^ A list of results, one for each constructor of type @t@. Each element is the 
-             -- result of applicatively applying the constructor to the results of the given function 
+             -> [f t] -- ^ A list of results, one for each constructor of type @t@. Each element is the
+             -- result of applicatively applying the constructor to the results of the given function
              -- for each field of the constructor.
   buildsRecA for sub _ = buildsA for sub
-  
-  {-# MINIMAL ctorIndex, (buildsA | buildsRecA) #-}
 
+  {-# MINIMAL ctorInfo, (buildsA | buildsRecA) #-}
+
 -- | Add an instance for this class if the data type has exactly one constructor.
 --
 --   This class has no methods.
 class ADT t => ADTRecord t where
 
 -- | `buildsA` specialized to the `Identity` applicative functor.
-builds :: (ADT t, Constraints t c) 
-       => For c -> (forall s. c s => FieldInfo (t -> s) -> s) -> [t]
-builds for f = runIdentity <$> buildsA for (Identity . f)  
+builds :: (ADT t, Constraints t c)
+       => for c -> (forall s. c s => FieldInfo (t -> s) -> s) -> [t]
+builds for f = runIdentity <$> buildsA for (Identity . f)
 
 -- | `buildsA` specialized to the `Constant` applicative functor, which collects monoid values @m@.
-mbuilds :: forall t c m. (ADT t, Constraints t c, Monoid m) 
-        => For c -> (forall s. c s => FieldInfo (t -> s) -> m) -> [m]
+mbuilds :: forall t c m for. (ADT t, Constraints t c, Monoid m)
+        => for c -> (forall s. c s => FieldInfo (t -> s) -> m) -> [m]
 mbuilds for f = getConstant <$> (buildsA for (Constant . f) :: [Constant m t])
 
 -- | Transform a value by transforming each subcomponent.
 gmap :: (ADT t, Constraints t c)
-     => For c -> (forall s. c s => s -> s) -> t -> t
+     => for c -> (forall s. c s => s -> s) -> t -> t
 gmap for f t = builds for (\fld -> f (t ! fld)) `at` t
 
--- | Fold a value, by mapping each subcomponent to a monoid value and collecting those. 
+-- | Fold a value, by mapping each subcomponent to a monoid value and collecting those.
 gfoldMap :: (ADT t, Constraints t c, Monoid m)
-         => For c -> (forall s. c s => s -> m) -> t -> m
+         => for c -> (forall s. c s => s -> m) -> t -> m
 gfoldMap for f = getConstant . gtraverse for (Constant . f)
 
 -- | Applicative traversal given a way to traverse each subcomponent.
-gtraverse :: (ADT t, Constraints t c, Applicative f) 
-          => For c -> (forall s. c s => s -> f s) -> t -> f t
+gtraverse :: (ADT t, Constraints t c, Applicative f)
+          => for c -> (forall s. c s => s -> f s) -> t -> f t
 gtraverse for f t = buildsA for (\fld -> f (t ! fld)) `at` t
 
 -- | `builds` for data types with exactly one constructor
-build :: (ADTRecord t, Constraints t c) 
-      => For c -> (forall s. c s => FieldInfo (t -> s) -> s) -> t
+build :: (ADTRecord t, Constraints t c)
+      => for c -> (forall s. c s => FieldInfo (t -> s) -> s) -> t
 build for f = head $ builds for f
 
 -- | Derive a 0-ary operation by applying the operation to every subcomponent.
-op0 :: (ADTRecord t, Constraints t c) => For c -> (forall s. c s => s) -> t
+op0 :: (ADTRecord t, Constraints t c) => for c -> (forall s. c s => s) -> t
 op0 for op = build for (const op)
 
 -- | Derive a unary operation by applying the operation to every subcomponent.
-op1 :: (ADTRecord t, Constraints t c) => For c -> (forall s. c s => s -> s) -> t -> t
+op1 :: (ADTRecord t, Constraints t c) => for c -> (forall s. c s => s -> s) -> t -> t
 op1 for op t = build for (\fld -> op $ t ! fld)
 
 -- | Derive a binary operation by applying the operation to every subcomponent.
-op2 :: (ADTRecord t, Constraints t c) => For c -> (forall s. c s => s -> s -> s) -> t -> t -> t
+op2 :: (ADTRecord t, Constraints t c) => for c -> (forall s. c s => s -> s -> s) -> t -> t -> t
 op2 for op s t = build for (\fld -> (s ! fld) `op` (t ! fld))
 
 
@@ -202,18 +201,18 @@
 
 
 instance ADT () where
-  
+
   type Constraints () c = ()
   ctorInfo _ 0 = ctor "()"
-  buildsA For _ = [ pure () ]
+  buildsA _ _ = [ pure () ]
 
 instance ADTRecord () where
-  
+
 instance ADT (a, b) where
-  
+
   type Constraints (a, b) c = (c a, c b)
   ctorInfo _ 0 = ctor "(,)"
-  buildsA For f = [ (,) <$> f (FieldInfo fst) <*> f (FieldInfo snd) ]
+  buildsA _ f = [ (,) <$> f (FieldInfo fst) <*> f (FieldInfo snd) ]
 
 instance ADTRecord (a, b) where
 
@@ -221,10 +220,10 @@
 
   type Constraints (a, b, c) tc = (tc a, tc b, tc c)
   ctorInfo _ 0 = ctor "(,,)"
-  buildsA For f = [(,,) <$> f (FieldInfo (\(a, _, _) -> a))
-                        <*> f (FieldInfo (\(_, b, _) -> b))
-                        <*> f (FieldInfo (\(_, _, c) -> c))
-                  ]
+  buildsA _ f = [(,,) <$> f (FieldInfo (\(a, _, _) -> a))
+                      <*> f (FieldInfo (\(_, b, _) -> b))
+                      <*> f (FieldInfo (\(_, _, c) -> c))
+                ]
 
 instance ADTRecord (a, b, c) where
 
@@ -232,11 +231,11 @@
 
   type Constraints (a, b, c, d) tc = (tc a, tc b, tc c, tc d)
   ctorInfo _ 0 = ctor "(,,,)"
-  buildsA For f = [(,,,) <$> f (FieldInfo (\(a, _, _, _) -> a))
-                         <*> f (FieldInfo (\(_, b, _, _) -> b))
-                         <*> f (FieldInfo (\(_, _, c, _) -> c))
-                         <*> f (FieldInfo (\(_, _, _, d) -> d))
-                  ]
+  buildsA _ f = [(,,,) <$> f (FieldInfo (\(a, _, _, _) -> a))
+                       <*> f (FieldInfo (\(_, b, _, _) -> b))
+                       <*> f (FieldInfo (\(_, _, c, _) -> c))
+                       <*> f (FieldInfo (\(_, _, _, d) -> d))
+                ]
 
 instance ADTRecord (a, b, c, d) where
 
@@ -248,7 +247,7 @@
   ctorInfo _ 1 = ctor "True"
 
   type Constraints Bool c = ()
-  buildsA For _ = [ pure False, pure True ]
+  buildsA for _ = [ pure False, pure True ]
 
 instance ADT (Either a b) where
 
@@ -258,11 +257,11 @@
   ctorInfo _ 1 = ctor "Right"
 
   type Constraints (Either a b) c = (c a, c b)
-  buildsA For f = 
+  buildsA for f =
     [ Left  <$> f (FieldInfo (\(Left a)  -> a))
     , Right <$> f (FieldInfo (\(Right a) -> a))
     ]
-    
+
 instance ADT (Maybe a) where
 
   ctorIndex Nothing = 0
@@ -271,7 +270,7 @@
   ctorInfo _ 1 = ctor "Just"
 
   type Constraints (Maybe a) c = c a
-  buildsA For f = 
+  buildsA for f =
     [ pure Nothing
     , Just <$> f (FieldInfo fromJust)
     ]
@@ -284,7 +283,6 @@
   ctorInfo _ 1 = CtorInfo ":" False (Infix RightAssociative 5)
 
   type Constraints [a] c = (c a, c [a])
-  buildsRecA For sub rec = 
+  buildsRecA for sub rec =
     [ pure []
     , (:) <$> sub (FieldInfo head) <*> rec (FieldInfo tail)]
-  
diff --git a/src/Generics/OneLiner/ADT1.hs b/src/Generics/OneLiner/ADT1.hs
--- a/src/Generics/OneLiner/ADT1.hs
+++ b/src/Generics/OneLiner/ADT1.hs
@@ -1,17 +1,16 @@
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Generics.OneLiner.ADT1
--- Copyright   :  (c) Sjoerd Visscher 2012
 -- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  sjoerd@w3future.com
 -- Stability   :  experimental
 -- Portability :  non-portable
 --
--- This module is for writing generic functions on algebraic data types 
--- of kind @* -> *@. 
+-- This module is for writing generic functions on algebraic data types
+-- of kind @* -> *@.
 -- These data types must be an instance of the `ADT1` type class.
--- 
+--
 -- Here's an example how to write such an instance for this data type:
 --
 -- @
@@ -25,13 +24,13 @@
 --   `ctorInfo` _ 0 = `ctor` \"A\"
 --   `ctorInfo` _ 1 = `ctor` \"B\"
 --   type `Constraints` T c = (c [], c T)
---   `buildsRecA` `For` par sub rec = 
+--   `buildsRecA` _ par sub rec =
 --     [ A `<$>` sub (`component` (\\(A l) -> l)
 --     , B `<$>` par (`param` (\\(B a _) -> a)) `<*>` rec (`component` (\\(B _ t) -> t))
 --     ]
 -- @
 -----------------------------------------------------------------------------
-{-# LANGUAGE 
+{-# LANGUAGE
     RankNTypes
   , TypeFamilies
   , TypeOperators
@@ -46,26 +45,26 @@
     module Generics.OneLiner.Info
   , Constraint
     -- | The kind of constraints
-  
+
     -- * The @ADT1@ type class
   , ADT1(..)
   , ADT1Record(..)
   , For(..)
   , Extract(..)
   , (:~>)(..)
-  
+
     -- * Helper functions
   , (!)
   , (!~)
   , at
   , param
   , component
-  
+
   -- * Derived traversal schemes
   , builds
   , mbuilds
   , build
-  
+
   ) where
 
 import Generics.OneLiner.Info
@@ -90,68 +89,68 @@
 -- Where @Show@ can be any class.
 data For (c :: (* -> *) -> Constraint) = For
 
--- | Type class for algebraic data types of kind @* -> *@. Minimal implementation: `ctorIndex` and either `buildsA`
+-- | Type class for algebraic data types of kind @* -> *@. Implement either `buildsA`
 -- if the type @t@ is not recursive, or `buildsRecA` if the type @t@ is recursive.
 class ADT1 t where
 
   -- | Gives the index of the constructor of the given value in the list returned by `buildsA` and `buildsRecA`.
   ctorIndex :: t a -> Int
   ctorIndex _ = 0
-  
+
   -- | @ctorInfo n@ gives constructor information, f.e. its name, for the @n@th constructor.
   --   The first argument is a dummy argument and can be @(undefined :: t a)@.
   ctorInfo :: t a -> Int -> CtorInfo
 
-  -- | The constraints needed to run `buildsA` and `buildsRecA`. 
+  -- | The constraints needed to run `buildsA` and `buildsRecA`.
   -- It should be a list of all the types of the subcomponents of @t@, each applied to @c@.
   type Constraints t (c :: (* -> *) -> Constraint) :: Constraint
   buildsA :: (Constraints t c, Applicative f)
-          => For c -- ^ Witness for the constraint @c@.
+          => for c -- ^ Witness for the constraint @c@.
           -> (FieldInfo (Extract t) -> f b)
           -> (forall s. c s => FieldInfo (t :~> s) -> f (s b))
           -> [f (t b)]
-          
+
   default buildsA :: (c t, Constraints t c, Applicative f)
-                  => For c
+                  => for c
                   -> (FieldInfo (Extract t) -> f b)
                   -> (forall s. c s => FieldInfo (t :~> s) -> f (s b))
                   -> [f (t b)]
-  buildsA for param sub = buildsRecA for param sub sub 
+  buildsA for param sub = buildsRecA for param sub sub
 
   buildsRecA :: (Constraints t c, Applicative f)
-             => For c -- ^ Witness for the constraint @c@.
+             => for c -- ^ Witness for the constraint @c@.
              -> (FieldInfo (Extract t) -> f b)
              -> (forall s. c s => FieldInfo (t :~> s) -> f (s b))
              -> (FieldInfo (t :~> t) -> f (t b))
              -> [f (t b)]
   buildsRecA for param sub _ = buildsA for param sub
-  
-  {-# MINIMAL ctorIndex, (buildsA | buildsRecA) #-}
 
+  {-# MINIMAL ctorInfo, (buildsA | buildsRecA) #-}
+
 -- | Add an instance for this class if the data type has exactly one constructor.
 --
 --   This class has no methods.
 class ADT1 t => ADT1Record t where
 
 -- | `buildsA` specialized to the `Identity` applicative functor.
-builds :: (ADT1 t, Constraints t c) 
-       => For c
+builds :: (ADT1 t, Constraints t c)
+       => for c
        -> (FieldInfo (Extract t) -> b)
        -> (forall s. c s => FieldInfo (t :~> s) -> s b)
        -> [t b]
 builds for f g = runIdentity <$> buildsA for (Identity . f) (Identity . g)
 
 -- | `buildsA` specialized to the `Constant` applicative functor, which collects monoid values @m@.
-mbuilds :: forall t c m. (ADT1 t, Constraints t c, Monoid m) 
-        => For c
+mbuilds :: forall t c m for. (ADT1 t, Constraints t c, Monoid m)
+        => for c
         -> (FieldInfo (Extract t) -> m)
         -> (forall s. c s => FieldInfo (t :~> s) -> m)
         -> [m]
 mbuilds for f g = getConstant <$> (buildsA for (Constant . f) (Constant . g) :: [Constant m (t b)])
 
 -- | `builds` for data types with exactly one constructor
-build :: (ADT1Record t, Constraints t c) 
-       => For c
+build :: (ADT1Record t, Constraints t c)
+       => for c
        -> (FieldInfo (Extract t) -> b)
        -> (forall s. c s => FieldInfo (t :~> s) -> s b)
        -> t b
@@ -177,27 +176,27 @@
 
 
 instance ADT1 Maybe where
-  
+
   ctorIndex Nothing = 0
   ctorIndex Just{}  = 1
   ctorInfo _ 0 = ctor "Nothing"
   ctorInfo _ 1 = ctor "Just"
-  
+
   type Constraints Maybe c = ()
-  buildsA For f _ = 
+  buildsA _ f _ =
     [ pure Nothing
     , Just <$> f (param fromJust)
     ]
-  
+
 instance ADT1 [] where
-  
+
   ctorIndex []    = 0
   ctorIndex (_:_) = 1
   ctorInfo _ 0 = ctor "[]"
   ctorInfo _ 1 = CtorInfo ":" False (Infix RightAssociative 5)
-  
+
   type Constraints [] c = c []
-  buildsRecA For p _ r = 
+  buildsRecA _ p _ r =
     [ pure []
     , (:) <$> p (param head) <*> r (component tail)
     ]
diff --git a/src/Generics/OneLiner/Functions.hs b/src/Generics/OneLiner/Functions.hs
--- a/src/Generics/OneLiner/Functions.hs
+++ b/src/Generics/OneLiner/Functions.hs
@@ -1,7 +1,6 @@
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Generics.OneLiner.Functions
--- Copyright   :  (c) Sjoerd Visscher 2012
 -- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  sjoerd@w3future.com
@@ -33,11 +32,11 @@
 import qualified Control.Monad.Trans.Class as T
 
 eqADT :: (ADT t, Constraints t Eq) => t -> t -> Bool
-eqADT s t = ctorIndex s == ctorIndex t && 
+eqADT s t = ctorIndex s == ctorIndex t &&
   getAll (mbuilds (For :: For Eq) (\fld -> All $ s ! fld == t ! fld) `at` s)
 
 compareADT :: (ADT t, Constraints t Ord) => t -> t -> Ordering
-compareADT s t = compare (ctorIndex s) (ctorIndex t) <> 
+compareADT s t = compare (ctorIndex s) (ctorIndex t) <>
   mbuilds (For :: For Ord) (\fld -> compare (s ! fld) (t ! fld)) `at` s
 
 minBoundADT :: (ADT t, Constraints t Bounded) => t
@@ -51,18 +50,18 @@
   where
     CtorInfo name rec fty = ctorInfo t (ctorIndex t)
 
-    inner (Infix _ d') = showParen (d > d') $ let [f0, f1] = fields (d' + 1) in 
+    inner (Infix _ d') = showParen (d > d') $ let [f0, f1] = fields (d' + 1) in
       f0 . showChar ' ' . showString name . showChar ' ' . f1
     inner _ = showParen (d > 10) $ showString name . showChar ' ' . body
 
-    body = if rec 
+    body = if rec
       then showChar '{' . conc (showString ", ") (fields 0) . showChar '}'
       else conc (showString " ") (fields 11)
 
     fields d' = mbuilds (For :: For Show) (return . f d') `at` t
 
     f :: Show s => Int -> FieldInfo (t -> s) -> ShowS
-    f d' info = if rec 
+    f d' info = if rec
       then showString (selectorName info) . showString " = " . showsPrec d' (t ! info)
       else showsPrec d' (t ! info)
 
@@ -73,11 +72,11 @@
   where
     ctorReads = ctorParse <$> zip (fmap (ctorInfo (undefined :: t)) [0..]) (buildsA (For :: For Read) fieldParse)
 
-    ctorParse (CtorInfo name _ (Infix _ d), getFields) = 
+    ctorParse (CtorInfo name _ (Infix _ d), getFields) =
       let flds = evalStateT getFields $ do { Symbol name' <- lexP; guard (name' == name) }
       in prec d flds
 
-    ctorParse (CtorInfo name rec _, getFields) = 
+    ctorParse (CtorInfo name rec _, getFields) =
       let flds = evalStateT getFields (return ())
       in prec (if rec then 11 else 10) $ do
         Ident name' <- lexP
@@ -98,7 +97,7 @@
       Punc "=" <- lexP
       res <- reset readPrec
       parseOp
-      return (res, return ())  
+      return (res, return ())
     fieldParse _ = StateT $ \parseOp -> do
       res <- step readPrec
       parseOp
diff --git a/src/Generics/OneLiner/Functions1.hs b/src/Generics/OneLiner/Functions1.hs
--- a/src/Generics/OneLiner/Functions1.hs
+++ b/src/Generics/OneLiner/Functions1.hs
@@ -1,7 +1,6 @@
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Generics.OneLiner.Functions1
--- Copyright   :  (c) Sjoerd Visscher 2013
 -- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  sjoerd@w3future.com
diff --git a/src/Generics/OneLiner/Info.hs b/src/Generics/OneLiner/Info.hs
--- a/src/Generics/OneLiner/Info.hs
+++ b/src/Generics/OneLiner/Info.hs
@@ -1,7 +1,6 @@
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Generics.OneLiner.Info
--- Copyright   :  (c) Sjoerd Visscher 2012
 -- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  sjoerd@w3future.com
@@ -26,11 +25,15 @@
 data Associativity = LeftAssociative | RightAssociative | NotAssociative
   deriving (Eq, Show, Ord, Read)
 
-data FieldInfo p 
+data FieldInfo p
   = SelectorInfo
     { selectorName :: String
     , project      :: p
     }
   | FieldInfo
-    { project      :: p 
+    { project      :: p
     }
+
+instance Functor FieldInfo where
+  fmap f (SelectorInfo s p) = SelectorInfo s (f p)
+  fmap f (FieldInfo p) = FieldInfo (f p)
