diff --git a/CHANGELOG b/CHANGELOG
new file mode 100644
--- /dev/null
+++ b/CHANGELOG
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright 2012 Russell O'Connor
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+3. Neither the name of the author nor the names of his contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,4 @@
+#! /usr/bin/env runhaskell
+ 
+> import Distribution.Simple
+> main = defaultMain
diff --git a/lens-family-core.cabal b/lens-family-core.cabal
new file mode 100644
--- /dev/null
+++ b/lens-family-core.cabal
@@ -0,0 +1,50 @@
+name:               lens-family-core
+category:           Data
+version:            0.0.0
+license:            BSD3
+cabal-version:      >= 1.6
+license-file:       LICENSE
+author:             Russell O'Connor
+maintainer:         Russell O'Connor <roconnor@theorem.ca>
+stability:          experimental
+copyright:          Copyright (C) 2012 Russell O'Connor
+synopsis:           Haskell 98 Lens Families
+description:        Haskell 98 Lens Families
+build-type:         Simple
+extra-source-files: CHANGELOG
+description:        This package provide first class(†) functional references.
+                    In addition to the usual operations of getting, setting and composition, plus integration with the state monad, lens families provide some unique features:
+                    .
+                    * Polymorphic updating
+                    .
+                    * Cast projection functions to read-only lenses
+                    .
+                    * Cast semantic editor combinators to modify-only lenses
+                    .
+                    (†) For optimal first-class support use the @lens-family@ package with rank 2 / rank N polymorphism.
+                    "Lens.Family.Clone" allows for first-class support of lenses for those who require Haskell 98.
+
+source-repository head
+  type:     darcs
+  location: http://r6.ca/lens-family
+
+library
+  build-depends:
+    base                 >= 4       && < 5,
+    containers           >= 0.3     && < 0.5,
+    transformers         >= 0.2.0   && < 0.4
+
+  exposed-modules:
+    Lens.Family.Unchecked
+    Lens.Family.Clone
+    Lens.Family
+    Lens.Family.Stock
+    Lens.Family.State.Lazy
+    Lens.Family.State.Strict
+    Lens.Family.State
+
+  ghc-options:      -Wall
+
+  hs-source-dirs:
+                    src
+
diff --git a/src/Lens/Family.hs b/src/Lens/Family.hs
new file mode 100644
--- /dev/null
+++ b/src/Lens/Family.hs
@@ -0,0 +1,129 @@
+-- | This is the main module for end-users of lens-families.
+-- If you are not building your own lenses, but just using top-level defined lenses made by others, this is the only module you need.
+-- It provides '^.' for accessing fields and '^=' and '^%=' for setting and modifying fields.
+-- Lenses are composed with `Prelude..` from the @Prelude@ and `Prelude.id` is the identity lens.
+--
+-- /Warning/: Lenses are composed in the opposite order than most lens packages.
+-- Lenses in this library enjoy the following identities.
+--
+-- * @x ^. l1 . l2 === x ^. l1 ^. l2@
+--
+-- * @l1 . l2 ^%= f === l1 ^%= l2 ^%= f@
+--
+-- The identity lens behaves as follows.
+--
+-- * @x ^. id === x@
+--
+-- * @id ^%= f === f@
+--
+-- Lenses are implemented in van Laarhoven style.  Lenses have type @'Functor' f => (b -> f b) -> a -> f a@ and lens families have type @'Functor' f => (b x -> f (b x')) -> a x -> f (a x')@.
+--
+-- Remember that lenses and lens families can be used directly for functorial updates.
+-- For example, @sndL id@ gives you strength.
+--
+-- > sndL id :: Functor f => (a, f b) -> f (a, b)
+--
+-- Here is an example of code that uses the 'Maybe' functor to preserves sharing during update when possible.
+--
+-- > -- | 'sharedUpdate' returns the *identical* object if the update doesn't change anything.
+-- > -- This is useful for preserving sharing.
+-- > sharedUpdate :: Eq b => Lens Maybe a b -> (b -> b) -> a -> a
+-- > sharedUpdate lens f a = fromMaybe a (lens f' a)
+-- >  where
+-- >   f' b | fb == b  = Nothing
+-- >        | otherwise = Just fb
+-- >    where
+-- >     fb = f b
+--
+-- For stock lenses, see "Lens.Family.Stock".
+--
+-- To build your own lenses, see "Lens.Family.Unchecked".
+--
+-- References:
+--
+-- * <http://www.twanvl.nl/blog/haskell/cps-functional-references>
+--
+-- * <http://r6.ca/blog/20120623T104901Z.html>
+--
+-- * <http://comonad.com/reader/2012/mirrored-lenses/>
+--
+-- * <http://conal.net/blog/posts/semantic-editor-combinators>
+module Lens.Family
+  ( getting, setting
+  , (^.)
+  , (^%=)
+  , (^=)
+  -- * Pseudo-imperatives
+  , (^+=), (^*=), (^-=), (^/=), (^&&=), (^||=)
+  -- * Types
+  , GetterFamily, Getter
+  , SetterFamily, Setter
+  ) where
+
+import Lens.Family.Unchecked (LensFamily)
+
+newtype Getting c a = Getting { unGetting :: c }
+instance Functor (Getting c) where
+  fmap _ (Getting c) = Getting c
+
+newtype Setting a = Setting { unSetting :: a }
+instance Functor Setting where
+  fmap f (Setting a) = Setting (f a)
+
+type GetterFamily a a' b b' = LensFamily (Getting b) a a' b b'
+type Getter a b = GetterFamily a a b b
+
+type SetterFamily a a' b b' = LensFamily Setting a a' b b'
+type Setter a b = SetterFamily a a b b
+
+-- | 'getting' promotes a projection function to a read-only lens.
+-- To demote a lens to a projection function, use the section @(^. l)@.
+--
+-- >>> (3 :+ 4, "example") ^. fstL . getting abs
+-- 5.0 :+ 0.0
+getting :: (a -> b) -> GetterFamily a a' b b'
+getting p _ = Getting . p
+
+-- | 'setting' promotes a \"semantic editor combinator\" to a modify-only lens.
+-- To demote a lens to a semantic edit combinator, use the section @(l ^%=)@.
+--
+-- >>> setting map . fstL ^%= length $ [("The",0),("quick",1),("brown",1),("fox",2)]
+-- [(3,0),(5,1),(5,1),(3,2)]
+setting :: ((b -> b') -> a -> a') -> SetterFamily a a' b b'
+setting s f = Setting . s (unSetting . f)
+
+infixr 8 ^.
+
+-- | Access a field.
+(^.) :: a -> GetterFamily a a' b b' -> b
+x ^. l = unGetting $ l Getting x
+
+infixr 4 ^%=
+
+-- | Modify a field.
+(^%=) :: SetterFamily a a' b b' -> (b -> b') -> a -> a'
+l ^%= f = unSetting . l (Setting . f)
+
+-- | Set a field.
+infixr 4 ^=
+
+(^=) :: SetterFamily a a' b b' -> b' -> a -> a'
+l ^= b = l ^%= const b
+
+infixr 4 ^+=, ^-=, ^*=
+
+(^+=), (^-=), (^*=) :: Num b => Setter a b -> b -> a -> a
+f ^+= b = f ^%= (+ b)
+f ^-= b = f ^%= subtract b
+f ^*= b = f ^%= (* b)
+
+infixr 4 ^/=
+
+(^/=) :: Fractional b => Setter a b -> b -> a -> a
+f ^/= b = f ^%= (/ b)
+
+infixr 4 ^&&=, ^||=
+
+(^&&=), (^||=) :: Setter a Bool -> Bool -> a -> a
+f ^&&= b = f ^%= (&& b)
+f ^||= b = f ^%= (|| b)
diff --git a/src/Lens/Family/Clone.hs b/src/Lens/Family/Clone.hs
new file mode 100644
--- /dev/null
+++ b/src/Lens/Family/Clone.hs
@@ -0,0 +1,39 @@
+-- | This module is only provided for Haskell 98 compatibility.
+-- If you are able to use @Rank2Types@, I strongly advise you to instead use 'Lens.Family2.Stock.LensFamily' and 'Lens.Family2.Stock.Lens' from the lens-family package instead.
+-- 
+-- 'clone' allows one to circumvent the need for rank 2 types by allowing one to take a universal monomorphic lens instance and rederive a polymorphic instance.
+-- When you require a lens family parameter you use the type @'ClonerFamily' a a' b b'@ (or @'Cloner' a b@).
+-- Then, inside a @where@ clause, you use 'clone' to create a 'LensFamily' type.
+--
+-- For example.
+--
+-- > example :: ClonerFamily a a' b b' -> Example
+-- > example l = ... x ^. cl ... cl ^= y ...
+-- >  where
+-- >   cl x = clone l x
+--
+-- /Note/: It is important to eta-expand the definition of 'cl' to avoid the dreaded monomorphism restriction.
+--
+-- /Note/: Cloning is only need if you use both @Getter@s and @Setter@s in the function.
+-- Otherwise you only need to use the monomorphic 'Lens.Family.GetterFamily' \/ 'Lens.Family.Getter' or 'Lens.Family.SetterFamily' \/ 'Lens.Family.Setter'.
+module Lens.Family.Clone
+  ( clone
+  -- * Types
+  , LensFamily
+  , ClonerFamily, Cloner
+  ) where
+
+import Lens.Family.Unchecked (LensFamily)
+
+data Cloning b' b a = Cloning (b' -> a) b
+instance Functor (Cloning b' b) where
+  fmap f (Cloning g b) = Cloning (f . g) b
+
+type ClonerFamily a a' b b' = LensFamily (Cloning b' b) a a' b b'
+type Cloner a b = ClonerFamily a a b b
+
+-- | Converts a universal lens instance back into a polymorphic lens.
+clone :: Functor f => ClonerFamily a a' b b' -> LensFamily f a a' b b'
+clone univ f a = fmap g (f b)
+  where
+    Cloning g b = univ (Cloning id) a
diff --git a/src/Lens/Family/State.hs b/src/Lens/Family/State.hs
new file mode 100644
--- /dev/null
+++ b/src/Lens/Family/State.hs
@@ -0,0 +1,5 @@
+module Lens.Family.State 
+  ( module Lens.Family.State.Lazy
+  ) where
+
+import Lens.Family.State.Lazy
diff --git a/src/Lens/Family/State/Lazy.hs b/src/Lens/Family/State/Lazy.hs
new file mode 100644
--- /dev/null
+++ b/src/Lens/Family/State/Lazy.hs
@@ -0,0 +1,72 @@
+-- | Lenses allow you to use fields of the state of a state monad as if they were variables in an imperative language.
+-- 'access' is used to retrieve the value of a variable, and '~=' and '%=' allow you to set and modify a variable.
+-- C-style compound assignments are also provided.
+module Lens.Family.State.Lazy 
+  ( focus
+  , access
+  , (%=)
+  , (~=)
+  , (%%=)
+  -- * Compound Assignments
+  , (+=), (-=), (*=)
+  , (//=)
+  , (&&=), (||=)
+  -- * Types
+  , Focusing
+  ) where
+
+import Control.Monad (liftM)
+import Control.Monad.Trans.State.Lazy (StateT(..), get, modify)
+import Lens.Family (Getter, Setter, (^.), (^%=))
+import Lens.Family.Stock (Lens)
+
+{- all these Monad constraints could be weakened to Functor constraints -}
+
+newtype Focusing m c a = Focusing { unFocusing :: m (c, a) }
+instance Monad m => Functor (Focusing m c) where
+  fmap f (Focusing m) = Focusing (liftM (fmap f) m)
+
+-- | Lift a stateful operation on a field to a stateful operation on the whole state.
+-- This is a good way to call a \"subroutine\" that only needs access to part of the state.
+focus :: Monad m => Lens (Focusing m c) a b -> StateT b m c -> StateT a m c
+focus l m = StateT $ unFocusing . l (Focusing . (runStateT m))
+
+-- | Retrieve a field of the state
+access :: Monad m => Getter a b -> StateT a m b
+access l = (^. l) `liftM` get
+
+infix 4 %=
+
+-- | Modify a field of the state
+(%=) :: Monad m => Setter a b -> (b -> b) -> StateT a m ()
+l %= f = modify (l ^%= f)
+
+infix 4 ~=
+
+-- | Set a field of the state
+(~=) :: Monad m => Setter a b -> b -> StateT a m ()
+l ~= v = l %= const v
+
+infix 4 %%=
+
+-- | Modify a field of the state while returning another value
+(%%=) :: Monad m => Lens (Focusing m c) a b -> (b -> (c, b)) -> StateT a m c
+l %%= f = focus l (StateT (return . f))
+
+infixr 4 +=, -=, *=
+
+(+=), (-=), (*=) :: (Monad m, Num b) => Setter a b -> b -> StateT a m ()
+f += b = f %= (+ b)
+f -= b = f %= subtract b
+f *= b = f %= (* b)
+
+infixr 4 //=
+
+(//=) :: (Monad m, Fractional b) => Setter a b -> b -> StateT a m ()
+f //= b = f %= (/ b)
+
+infixr 4 &&=, ||=
+
+(&&=), (||=) :: Monad m => Setter a Bool -> Bool -> StateT a m ()
+f &&= b = f %= (&& b)
+f ||= b = f %= (|| b)
diff --git a/src/Lens/Family/State/Strict.hs b/src/Lens/Family/State/Strict.hs
new file mode 100644
--- /dev/null
+++ b/src/Lens/Family/State/Strict.hs
@@ -0,0 +1,72 @@
+-- | Lenses allow you to use fields of the state of a state monad as if they were variables in an imperative language.
+-- 'access' is used to retrieve the value of a variable, and '~=' and '%=' allow you to set and modify a variable.
+-- C-style compound assignments are also provided.
+module Lens.Family.State.Strict 
+  ( focus
+  , access
+  , (%=)
+  , (~=)
+  , (%%=)
+  -- * Compound Assignments
+  , (+=), (-=), (*=)
+  , (//=)
+  , (&&=), (||=)
+  -- * Types
+  , Focusing
+  ) where
+
+import Control.Monad (liftM)
+import Control.Monad.Trans.State.Strict (StateT(..), get, modify)
+import Lens.Family (Getter, Setter, (^.), (^%=))
+import Lens.Family.Stock (Lens)
+
+{- all these Monad constraints could be weakened to Functor constraints -}
+
+newtype Focusing m c a = Focusing { unFocusing :: m (c, a) }
+instance Monad m => Functor (Focusing m c) where
+  fmap f (Focusing m) = Focusing (liftM (fmap f) m)
+
+-- | Lift a stateful operation on a field to a stateful operation on the whole state.
+-- This is a good way to call a \"subroutine\" that only needs access to part of the state.
+focus :: Monad m => Lens (Focusing m c) a b -> StateT b m c -> StateT a m c
+focus l m = StateT $ unFocusing . l (Focusing . (runStateT m))
+
+-- | Retrieve a field of the state
+access :: Monad m => Getter a b -> StateT a m b
+access l = (^. l) `liftM` get
+
+infix 4 %=
+
+-- | Modify a field of the state
+(%=) :: Monad m => Setter a b -> (b -> b) -> StateT a m ()
+l %= f = modify (l ^%= f)
+
+infix 4 ~=
+
+-- | Set a field of the state
+(~=) :: Monad m => Setter a b -> b -> StateT a m ()
+l ~= v = l %= const v
+
+infix 4 %%=
+
+-- | Modify a field of the state while returning another value
+(%%=) :: Monad m => Lens (Focusing m c) a b -> (b -> (c, b)) -> StateT a m c
+l %%= f = focus l (StateT (return . f))
+
+infixr 4 +=, -=, *=
+
+(+=), (-=), (*=) :: (Monad m, Num b) => Setter a b -> b -> StateT a m ()
+f += b = f %= (+ b)
+f -= b = f %= subtract b
+f *= b = f %= (* b)
+
+infixr 4 //=
+
+(//=) :: (Monad m, Fractional b) => Setter a b -> b -> StateT a m ()
+f //= b = f %= (/ b)
+
+infixr 4 &&=, ||=
+
+(&&=), (||=) :: Monad m => Setter a Bool -> Bool -> StateT a m ()
+f &&= b = f %= (&& b)
+f ||= b = f %= (|| b)
diff --git a/src/Lens/Family/Stock.hs b/src/Lens/Family/Stock.hs
new file mode 100644
--- /dev/null
+++ b/src/Lens/Family/Stock.hs
@@ -0,0 +1,63 @@
+-- | This module contains lenses for common structures in Haskell.
+-- It also contains the lens combinators 'mergeL' and '***'.
+module Lens.Family.Stock
+  ( -- * Lens Combinators
+    mergeL
+  , (***)
+  -- * Stock Lenses
+  , fstL, sndL
+  , funL
+  , mapL, intMapL
+  , setL, intSetL
+  -- * Types
+  , LensFamily, Lens
+  ) where
+
+import Lens.Family.Unchecked (LensFamily, Lens, mkLens)
+import Lens.Family ((^.), (^=))
+import Lens.Family.Clone (ClonerFamily, clone)
+import qualified Data.Map as Map
+import qualified Data.IntMap as IntMap
+import qualified Data.Set as Set
+import qualified Data.IntSet as IntSet
+
+-- | Given two lens\/getter\/setter families with the same substructure, make a new lens\/getter\/setter on 'Either'.
+mergeL :: Functor f => LensFamily f a a' c c' -> LensFamily f b b' c c' -> LensFamily f (Either a b) (Either a' b') c c'
+mergeL la _  f (Left a)  = Left  `fmap` la f a
+mergeL _  lb f (Right b) = Right `fmap` lb f b
+
+-- I suspect there is a more clever way to define this function.
+-- | Given two lens families, make a new lens on their product.
+(***) :: Functor f => ClonerFamily a1 a1' b1 b1' -> ClonerFamily a2 a2' b2 b2' -> LensFamily f (a1, a2) (a1', a2') (b1, b2) (b1', b2')
+(***) l1 l2 f (a1, a2) = (\(v'1, v'2) -> (cl1 ^= v'1 $ a1, cl2 ^= v'2 $ a2)) `fmap` f (a1 ^. cl1, a2 ^. cl2)
+  where
+    cl1 x = clone l1 x
+    cl2 x = clone l2 x
+
+-- | Lens on the first element of a pair.
+fstL :: Functor f => LensFamily f (a, b) (a', b) a a'
+fstL f (a, b) = (\a' -> (a', b)) `fmap` f a
+
+-- | Lens on the second element of a pair.
+sndL :: Functor f => LensFamily f (a, b) (a, b') b b'
+sndL f (a, b) = (\b' -> (a, b')) `fmap` f b
+
+-- | Lens on a given point of a function.
+funL :: (Eq k, Functor f) => k -> Lens f (k -> v) v
+funL k f g = (\v' x -> if (k == x) then v' else g x) `fmap` f (g k)
+
+-- | Lens on a given point of a 'Map.Map'.
+mapL :: (Ord k, Functor f) => k -> Lens f (Map.Map k v) (Maybe v)
+mapL k = mkLens (Map.lookup k) (\m -> maybe (Map.delete k m) (\v' -> Map.insert k v' m))
+
+-- | Lens on a given point of a 'IntMap.IntMap'.
+intMapL :: (Functor f) => Int -> Lens f (IntMap.IntMap v) (Maybe v)
+intMapL k = mkLens (IntMap.lookup k) (\m -> maybe (IntMap.delete k m) (\v' -> IntMap.insert k v' m))
+
+-- | Lens on a given point of a 'Set.Set'.
+setL :: (Ord k, Functor f) => k -> Lens f (Set.Set k) Bool
+setL k = mkLens (Set.member k) (\m nv -> if nv then Set.insert k m else Set.delete k m)
+
+-- | Lens on a given point of a 'IntSet.IntSet'.
+intSetL :: (Functor f) => Int -> Lens f IntSet.IntSet Bool
+intSetL k = mkLens (IntSet.member k) (\m nv -> if nv then IntSet.insert k m else IntSet.delete k m)
diff --git a/src/Lens/Family/Unchecked.hs b/src/Lens/Family/Unchecked.hs
new file mode 100644
--- /dev/null
+++ b/src/Lens/Family/Unchecked.hs
@@ -0,0 +1,71 @@
+-- | /Caution/: Improper use of this module can lead to unexpected behaviour if the preconditions of the functions are not met.
+-- 
+-- A lens family is created by separating a substructure from the rest of its structure by a functor.
+-- How to create a lens family is best illustrated by the common example of a field of a record:
+--
+-- > data MyRecord a = MyRecord { _myA :: a, _myB :: Int }
+-- >
+-- > -- The use of type variables a and a' allow for polymorphic updates.
+-- > myA :: Functor f => LensFamily f (MyRecord a) (MyRecord a') a a'
+-- > myA f (MyRecord a b) = (\a' -> MyRecord a' b) `fmap` (f a)
+-- >
+-- > -- The field _myB is monomorphic, so we can use a plain Lens type.
+-- > -- However, the structure of the function is exactly the same as for LensFamily.
+-- > myB :: Functor f => Lens f (MyRecord a) Int
+-- > myB f (MyRecord a b) = (\b' -> MyRecord a b') `fmap` (f b)
+--
+-- By following this template you can safely build your own lenses.
+-- To use this template, you do not need anything from this module other than the type synonyms 'LensFamily' and 'Lens', and even they are optional.
+-- See the @lens-family-th@ package to generate this code using Template Haskell.
+--
+-- You can build lenses for more than just fields of records.
+-- Any value @lens :: Functor f => LensFamily f a a' b b'@ is well-defined when it satisfies the two van Laarhoven lens laws:
+--
+-- * @lens Identity === Identity@
+--
+-- * @
+-- lens (composeCoalgebroid f g) === composeCoalgebroid (lens f) (lens g)
+--  where
+--   composeCoalgebroid :: (Functor f, Functor g) => (b -> f c) -> (a -> g b) -> a -> (Compose g f) c
+--   composeCoalgebroid f g a = Compose $ f \`fmap\` g a === id
+-- @
+--
+-- The functions 'mkLens' and 'mkIsoLens' can also be used to construct lenses.
+-- The resulting lenses will be well-defined so long as their preconditions are satisfied.
+module Lens.Family.Unchecked 
+  ( mkLens
+  , mkIsoLens
+  -- * Types
+  , LensFamily, Lens
+  ) where
+
+type LensFamily f a a' b b' = (b -> f b') -> (a -> f a')
+type Lens f a b = LensFamily f a a b b
+
+-- | Build a lens from a @getter@ and @setter@ families.
+--
+-- /Caution/: In order for the generated lens family to be well-defined, you must ensure that the three lens laws hold:
+-- 
+-- * @getter (setter a b) === b@
+--
+-- * @setter a (getter a) === a@
+--
+-- * @setter (setter a b1) b2) === setter a b2@
+mkLens :: Functor f
+       => (a -> b) -- ^ getter
+       -> (a -> b' -> a') -- ^ setter
+       -> LensFamily f a a' b b'
+mkLens getter setter f a = fmap (setter a) (f (getter a))
+
+-- | Build a lens from isomorphism families.
+--
+-- /Caution/: In order for the generated lens family to be well-defined, you must ensure that the two isomorphism laws hold:
+-- 
+-- * @yin . yang === id@
+--
+-- * @yang . yin === id@
+mkIsoLens :: Functor f 
+          => (a -> b) -- ^ yin
+          -> (b' -> a') -- ^ yang
+          -> LensFamily f a a' b b'
+mkIsoLens getter setter = mkLens getter (const setter)
