diff --git a/Data/Yall.hs b/Data/Yall.hs
--- a/Data/Yall.hs
+++ b/Data/Yall.hs
@@ -31,7 +31,7 @@
 getM = L.getM
 
 -- | try to run the setter function on an outer and new inner value
-setM :: (a L.:~> b) -> b -> a -> Maybe a
+setM :: (a L.:~> b) -> a -> b -> Maybe a
 setM = L.setM 
 
 -- | try to modify the inner type of a value
diff --git a/Data/Yall/Iso.hs b/Data/Yall/Iso.hs
--- a/Data/Yall/Iso.hs
+++ b/Data/Yall/Iso.hs
@@ -24,8 +24,8 @@
      composing with other @Lens@ or @Iso@.
 
      Also note that for most of these @apply i . unapply i@ is not strictly
-     @id@, e.g. @zipI@ obviously truncates lists of differing length, etc.
-     This is officially not something I'm concerned about.
+     @id@ for the entire input domain, e.g. @zipI@ obviously truncates lists of
+     differing length, etc.  
   -}
   , wordsI, showI, linesI, curryI, enumI, integerI, rationalI, zipI
   , incrementI, incrementByI, consI
diff --git a/Data/Yall/Lens.hs b/Data/Yall/Lens.hs
--- a/Data/Yall/Lens.hs
+++ b/Data/Yall/Lens.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE MultiParamTypeClasses, TypeOperators, TypeFamilies , FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses, TypeOperators, TypeFamilies , FlexibleInstances, FlexibleContexts #-}
 module Data.Yall.Lens (
     {- | 
      The Lenses here are parameterized over two Monads (by convention @m@ and
@@ -46,21 +46,21 @@
 -- [[('a',0),('b',2),('c',3)],[('a',1),('b',0),('c',3)],[('a',1),('b',2),('c',0)]]
 
 
-    -- ** Lenses with monadic getters
+    , Lenses(..)
+
     , LensM
     , lensM
-    , getM, setM, modifyM 
     -- ** Monadic variants
     {- | The setter continuation is embedded in the getter\'s Monadic
        environment, so we offer several ways of combining different types of
-       getter environments(@m@) and setter environments (@w@), for Lenses
+       getter environments (@m@) and setter environments (@w@), for Lenses
        with complex effects.
+
+       Newtype wrappers around 'Lens' let us use the same 'Lenses' interface
+       for getting and setting for these various monad-combining schemes.
     -}
     , lensMW
-    , setW, modifyW
-    , setLiftM, setLiftW, setJoin
-    -- *** Monoid setters
-    , setEmpty, setEmptyM, setEmptyW
+    , LensLift(..) , LensJoin(..) , LensW(..)
 
     -- * Composing Lenses
     {- |
@@ -101,7 +101,8 @@
     , fstL, sndL
     , eitherL, (|||)
     , factorL, distributeL
-    , isoL
+    -- ** Lenses from Isomorphisms
+    , isoL , residualL
 
     -- * Convenience operators
     {- | The little \"^\" hats are actually superscript \"L\"s (for "Lens") that have fallen over.
@@ -137,7 +138,6 @@
 import Control.Monad
 import Control.Monad.Trans.Class
 import Data.Functor.Identity
-import Data.Monoid
 
 
 {-
@@ -148,34 +148,39 @@
 -- constrain these 'm's to Monad?
 newtype Lens w m a b = Lens { runLens :: a -> m (b -> w a, b) }
 
--- | A lens in which the setter returns its result in the trivial identity 
--- monad. This is appropriate e.g. for traditional partial lenses, where there is
--- a potential that the lens could fail only on the /outer/ constructor.
+-- | A lens in which the setter returns its result in the trivial 'Identity'
+-- monad. This is appropriate e.g. for traditional partial lenses on sum types,
+-- where there is a potential that the lens could fail only on the /outer/
+-- constructor.
 type LensM = Lens Identity
 
 -- | Create a monadic lens from a getter and setter
 lensM :: (Monad m)=> (a -> m b) -> (a -> m (b -> a)) -> LensM m a b
 lensM g = lensMW g . fmap (liftM $ fmap return)
 
--- | get, returning the result in a Monadic environment. This is appropriate
--- e.g. for traditional partial lenses on multi-constructor types. See also
--- 'setM'
-getM :: (Monad m)=> Lens w m a b -> a -> m b
-getM (Lens f) = liftM snd . f
+-- | A class for our basic (monadic) lens operations. Minimal complete
+-- definition is 'getM' and 'setM'
+class (Monad m)=> Lenses l m where
+    getM :: l m a b -> a -> m b
+    setM :: l m a b -> a -> b -> m a
+    modifyM :: l m a b -> (b -> b) -> a -> m a
+    modifyM l f a = getM l a >>= setM l a . f
 
--- | set, returning the result in the getter\'s Monadic environment, running 
--- the setter\'s trivial Identity monad. 
-setM :: (Monad m)=> LensM m a b -> b -> a -> m a
-setM (Lens f) b = liftM (runIdentity . ($ b) . fst) . f
+-- helpers:
+getterM :: Monad m => Lens t m a r -> a -> m r
+getterM (Lens f) = liftM snd . f
+setterM :: Monad m => Lens t m a b -> a -> m (b -> t a)
+setterM (Lens f) = liftM fst . f
 
--- | modify the inner value within the getter\'s Monadic environment 
-modifyM :: (Monad m)=> LensM m a b -> (b -> b) -> a -> m a
-modifyM (Lens f) g a = do
-    (bWa, b) <- f a
-    return (runIdentity $ bWa $ g b)
+instance (Monad m)=> Lenses (Lens Identity) m where
+    getM = getterM
+    -- is let-floating effective here? Can snd be GCed after 'setM l a'?
+    setM l a = let mba = setterM l a
+                in \b-> liftM (runIdentity . ($ b)) mba
+    modifyM (Lens f) g a = do
+        (bWa, b) <- f a
+        return (runIdentity $ bWa $ g b)
 
-modifyW :: (Monad w)=> Lens w Identity a b -> (b -> b) -> a -> w a
-modifyW (Lens f) g = uncurry ($) . second g . runIdentity . f
 
 -- | Create a monadic Lens from a setter and getter.
 --
@@ -183,26 +188,44 @@
 lensMW :: (Monad m)=> (a -> m b) -> (a -> m (b -> w a)) -> Lens w m a b
 lensMW g s = Lens $ \a-> liftM2 (,) (s a) (g a)
 
--- | set, with Monadic setter & pure getter
-setW :: (Monad w)=> Lens w Identity a b -> b -> a -> w a
-setW (Lens f) b = ($ b) . fst . runIdentity . f 
 
--- | set, 'lift'ing the outer (getter\'s) Monadic environment to the type of
--- the setter monad transformer.
-setLiftM :: (Monad (t m), MonadTrans t, Monad m)=> Lens (t m) m a b -> b -> a -> t m a  
-setLiftM (Lens f) b = join . liftM (($ b) . fst) . lift . f 
+------------------ MONADIC VARIANTS: ---------------------
+-- TODO: derive all classes
 
--- | set, like 'setLiftM' but we 'lift' the /inner/ setter\'s environment to
--- the outer getter monad transformer.
-setLiftW :: (MonadTrans t, Monad (t w), Monad w)=> Lens w (t w) a b -> b -> a -> t w a
-setLiftW (Lens f) b a = lift . ($ b) . fst =<< f a 
+-- | lenses in which set/get should 'lift' the inner monad @w@ to @m@
+newtype LensLift w m a b = LLift (Lens w m a b)
 
+instance (MonadTrans t, Monad (t w), Monad w)=> Lenses (LensLift w) (t w) where
+    getM (LLift l) = getterM l
+    setM (LLift l) a = let mba = setterM l a
+                        in \b-> lift . ($ b) =<< mba
+
+
+-- | lenses in which @m@ == @w@ and we would like to 'join' the two in get/set
+newtype LensJoin m a b = LJoin (Lens m m a b)
+
+instance (Monad m)=> Lenses LensJoin m where
+    getM (LJoin l) = getterM l
+    setM (LJoin l) a = let mba = setterM l a
+                        in \b-> mba >>= ($ b)
+
+-- | lenses in which only the setter @w@ is monadic
+newtype LensW w a b = LW (Lens w Identity a b)
+
+instance (Monad w)=> Lenses LensW w where
+    getM (LW l) = return . get l
+    setM (LW (Lens f)) a = let bwa = fst $ runIdentity $ f a
+                            in bwa
+    modifyM (LW (Lens f)) g = uncurry ($) . second g . runIdentity . f
+
+
+-- -- | set, 'lift'ing the outer (getter\'s) Monadic environment to the type of
+-- -- the setter monad transformer.
+-- setLiftM :: (Monad (t m), MonadTrans t, Monad m)=> Lens (t m) m a b -> b -> a -> t m a  
+-- setLiftM (Lens f) b = join . liftM (($ b) . fst) . lift . f 
+
     
 
--- | set, combining the effects of the identical setter and getter Monads with
--- 'join'.
-setJoin :: (Monad m)=> Lens m m a b -> b -> a -> m a
-setJoin (Lens f) b a = f a >>= ($ b) . fst
 
 instance (Monad w, Monad m)=> Category (Lens w m) where
     id = Lens $ return . (,) return
@@ -322,10 +345,17 @@
 
 
 
--- | Convert an isomorphism to a 'Lens'
+-- | Convert an isomorphism @i@ to a 'Lens'. When @apply i . unapply i =
+-- unapply i . apply i = id@, the resulting lens will be well-behaved.
 isoL :: (Monad m, Monad w)=> Iso m w a b -> Lens m w a b
 isoL (Iso f g) = Lens $ fmap (liftM ((,) g)) f
 
+-- | Convert to a Lens an isomorphism between a value @a@ and a tuple of a
+-- value @b@ with some \"residual\" value @r@. 
+residualL :: (Monad m, Monad w)=> Iso m w a (b,r) -> Lens m w a b
+residualL (Iso f g) = Lens $ \a-> do
+    (b,r) <- f a
+    return (\b'-> g (b',r), b)
 
 -- -------------------
 -- Simple API
@@ -343,16 +373,16 @@
 --
 -- > get l = runIdentity . getM l
 get :: Lens w Identity a b -> a -> b
-get l = runIdentity . getM l
+get l = runIdentity . liftM snd . runLens l
 
 -- | Run the getter function of a pure lens
 --
--- > set l b = runIdentity . setM l b
-set :: (a :-> b) -> b -> a -> a
-set l b = runIdentity . setM l b
+-- > set l b = runIdentity . setM l a
+set :: (a :-> b) -> a -> b -> a
+set l a = runIdentity . setM l a
 
 modify :: (a :-> b) -> (b -> b) -> a -> a
-modify l b = runIdentity . modifyM l b
+modify l f = runIdentity . modifyM l f
 
 -- | a lens that can fail in the Maybe monad on the outer type. Suitable for a
 -- normal lens on a multi-constructor type. The more general 'setM', 'getM', etc.
@@ -360,25 +390,32 @@
 type (:~>) = LensM Maybe
 
 
--- TODO: can we convert an Iso to this kind of type?? Is this more appropriate living in Iso??
-
--- | Set an inner value on an initially 'mempty' value.
+-- TODO: get rid of this and instead have a conversion to Iso function
+--       rename other to-Iso conversion functions to make some kind of sense
+--           lensI :: Monoid a=> Lens a b -> Iso a b
+--           lensI l = Iso (getM l) (flip (setM l) mempty)
+--       does this make an isomorphism of a well-behaved lens?
+--           get l . flip (set l) mempty == id ?
+--              get . set mempty OKAY
+--           flip (set l) mempty . get l == id ?
+--              set mempty $ get a  -- only 'id' when 'a' is 'mempty' as well.
+--              LAW WE ASSUME HOLDS: set a $ get a
+--       and is isoL . lensI == id?
+--  CONSIDER...
+--       what properties does an Iso have to have for isoL to produce a well-behaved lens?
+--          put (Iso _ g) b _ = g b
+--          get (Iso f _) a   = f a
 --
--- > setZero l b = set l b mzero
-setEmpty :: Monoid a => (a :-> b) -> b -> a
-setEmpty l b = set l b mempty
+--          get . put b  =  f (g b) -- f and g must be truly isomorphic for resulting lens to be well-behaved
+--          put . get  =  g (f a)   
+--          put b . put b  =   g b  -- doesn't matter, as put only depends on 'b'
+--  OR... 
+--       rename these below "fill" (since we're "setting" an empty)
+--  OR... 
+--       remove and just use Isos in our example.
 
--- | > setZeroM l b = setM l b mzero
-setEmptyM :: (Monoid a, Monad m) => LensM m a b -> b -> m a
-setEmptyM l b = setM l b mempty
 
--- | > setEmptyW l b = setW l b mempty
-setEmptyW :: (Monoid a, Monad w) => Lens w Identity a b -> b -> w a
-setEmptyW l b = setW l b mempty
 
---TODO: more set variations? getEmpty?
-
-
 -- OPERATORS: ------------------------
 
 -- | > (^$) = get
@@ -386,5 +423,5 @@
 (^$) = get
 
 -- | > ma ^>>= l = ma >>= getM l
-(^>>=) :: (Monad m)=> m a -> Lens w m a b -> m b
+(^>>=) :: (Lenses l m)=> m a -> l m a b -> m b
 ma ^>>= l = ma >>= getM l
diff --git a/yall.cabal b/yall.cabal
--- a/yall.cabal
+++ b/yall.cabal
@@ -1,6 +1,6 @@
 Name:                yall
 
-Version:             0.1
+Version:             0.2
 
 Synopsis:            Lenses with a southern twang
 
@@ -30,9 +30,16 @@
                      and optionally "Data.Yall.Iso". "Data.Yall" is a simplified,
                      but mostly-compatible, version of a subset of "Data.Yall.Lens".
                      .
-                     TODOs:
+                     /TODOs/:
                      .
                      - a module providing template haskell deriving of Lenses
+                     .
+                     /CHANGES/:
+                     .
+                     - remove 'setEmpty' variants only useful on lenses better expressed in Iso
+                     - create a class for lens operations, supporting...
+                     - use newtype wrappers for different monadic lifting schemes
+                     - better ordering for set, allowing let-floating for partial application
 
 
 Homepage:            http://brandon.si/code/yall/
