diff --git a/CHANGES b/CHANGES
new file mode 100644
--- /dev/null
+++ b/CHANGES
@@ -0,0 +1,8 @@
+Version 3.3.0
+
+* Remove 'RunStateM'
+  Simplifies the library without loosing functionality.
+  It seems that we can get the same behavior by just using 'get' and 'set'.
+
+* Add functions that use a monad morphism to "derive" implementations
+  of most of the funcitons in the library.
diff --git a/monadLib.cabal b/monadLib.cabal
--- a/monadLib.cabal
+++ b/monadLib.cabal
@@ -1,20 +1,18 @@
 Name:           monadLib
-Version:        3.1.0
+Version:        3.3.0
 License:        BSD3
 License-file:   LICENSE
 Author:         Iavor S. Diatchki
-Maintainer:     diatchki@csee.ogi.edu
-Homepage:       http://www.csee.ogi.edu/~diatchki/monadLib
+Maintainer:     diatchki@galois.com
+Homepage:       http://www.galois.com/~diatchki/monadLib
 Category:       Monads
 Synopsis:       A collection of monad transformers.
 Description:    A collection of monad transformers.
 hs-source-dirs: src
 Build-Depends:  base
-Extra-source-files: LICENSE README
-Exposed-modules: 
-                 MonadLib
-                 Monads
-Extensions:     
-  MultiParamTypeClasses, FunctionalDependencies
+Extra-source-files: LICENSE, README, CHANGES
+Exposed-modules: MonadLib, Monads
+Extensions:
+  MultiParamTypeClasses, FunctionalDependencies, Rank2Types
 GHC-options:    -O2 -W -fallow-undecidable-instances
 
diff --git a/src/MonadLib.hs b/src/MonadLib.hs
--- a/src/MonadLib.hs
+++ b/src/MonadLib.hs
@@ -5,9 +5,9 @@
 module MonadLib (
   -- * Types
   -- $Types
-  Id, Lift, ReaderT, WriterT, StateT, ExceptionT, ContT,
+  Id, Lift, IdT, ReaderT, WriterT, StateT, ExceptionT, ContT,
 
-  -- * Lifting 
+  -- * Lifting
   -- $Lifting
   MonadT(..), BaseM(..),
 
@@ -17,15 +17,22 @@
   Label, labelCC, jump,
 
   -- * Execution
- 
+
   -- ** Eliminating Effects
   -- $Execution
-  runId, runLift, runReaderT, runWriterT, runStateT, runExceptionT, runContT, 
+  runId, runLift,
+  runIdT, runReaderT, runWriterT, runStateT, runExceptionT, runContT,
 
   -- ** Nested Execution
   -- $Nested_Exec
-  RunReaderM(..), RunWriterM(..), RunStateM(..), RunExceptionM(..),
+  RunReaderM(..), RunWriterM(..), RunExceptionM(..),
 
+  -- * Deriving functions
+  Iso(..), derive_fmap, derive_return, derive_bind, derive_fail, derive_mfix,
+  derive_ask, derive_put, derive_get, derive_set, derive_raise, derive_callCC,
+  derive_local, derive_collect, derive_try,
+  derive_lift, derive_inBase,
+
   -- * Miscellaneous
   version,
   module Control.Monad
@@ -34,49 +41,53 @@
 import Control.Monad
 import Control.Monad.Fix
 import Data.Monoid
+import Prelude hiding (Ordering(..))
 
 -- | The current version of the library.
 version :: (Int,Int,Int)
-version = (3,1,0)
+version = (3,3,0)
 
 
 -- $Types
--- 
+--
 -- The following types define the representations of the
 -- computation types supported by the library.
 -- Each type adds support for a different effect.
 
 -- | Computations with no effects.
-newtype Id a              = I a                         
+newtype Id a              = I a
 
--- | Computation with no effects (stritc).
+-- | Computation with no effects (strict).
 data Lift a               = L a
 
+-- | Add nothing.  Useful as a placeholder.
+newtype IdT m a           = IT (m a)
+
 -- | Add support for propagating a context.
-newtype ReaderT    i m a  = R (i -> m a)                
+newtype ReaderT    i m a  = R (i -> m a)
 
 -- | Add support for collecting values.
-newtype WriterT    i m a  = W (m (a,i))            
+newtype WriterT    i m a  = W (m (a,i))
 
 -- | Add support for threading state.
-newtype StateT     i m a  = S (i -> m (a,i))           
+newtype StateT     i m a  = S (i -> m (a,i))
 
 -- | Add support for exceptions.
-newtype ExceptionT i m a  = X (m (Either i a))          
+newtype ExceptionT i m a  = X (m (Either i a))
 
 -- | Add support for jumps.
-newtype ContT      i m a  = C ((a -> m i) -> m i)       
+newtype ContT      i m a  = C ((a -> m i) -> m i)
 
 
 
 -- $Execution
--- 
+--
 -- The following functions eliminate the outermost effect
 -- of a computation by translating a computation into an
--- equivalent computation in the underlying monad.  
--- (The exception is 'Id' which is not a monad transformer 
--- but an ordinary monad, and so, its run operation simply
--- eliminates the monad.)
+-- equivalent computation in the underlying monad.
+-- (The exceptions are 'Id' and 'Lift' which are not transformers
+-- but ordinary monas and so, their run operations simply
+-- eliminate the monad.)
 
 
 -- | Get the result of a pure computation.
@@ -87,6 +98,11 @@
 runLift       :: Lift a -> a
 runLift (L a) = a
 
+
+-- | Remove an identity layer.
+runIdT        :: IdT m a -> m a
+runIdT (IT a)  = a
+
 -- | Execute a reader computation in the given context.
 runReaderT    :: i -> ReaderT i m a -> m a
 runReaderT i (R m) = m i
@@ -102,7 +118,7 @@
 runStateT i (S m) = m i
 
 -- | Execute a computation with exceptions.
--- Successful results are tagged with 'Right', 
+-- Successful results are tagged with 'Right',
 -- exceptional results are tagged with 'Left'.
 runExceptionT :: ExceptionT i m a -> m (Either i a)
 runExceptionT (X m) = m
@@ -114,11 +130,11 @@
 
 
 -- $Lifting
--- 
+--
 -- The following operations allow us to promote computations
 -- in the underlying monad to computations that support an extra
 -- effect.  Computations defined in this way do not make use of
--- the new effect but can be combined with other operations that 
+-- the new effect but can be combined with other operations that
 -- utilize the effect.
 
 class MonadT t where
@@ -128,9 +144,10 @@
 -- It is interesting to note that these use something the resembles
 -- the non-transformer 'return's.
 
+instance MonadT IdT            where lift m = IT m
 instance MonadT (ReaderT    i) where lift m = R (\_ -> m)
 instance MonadT (StateT     i) where lift m = S (\s -> liftM (\a -> (a,s)) m)
-instance (Monoid i) => 
+instance (Monoid i) =>
          MonadT (WriterT    i) where lift m = W (liftM (\a -> (a,mempty)) m)
 instance MonadT (ExceptionT i) where lift m = X (liftM Right m)
 instance MonadT (ContT      i) where lift m = C (m >>=)
@@ -139,16 +156,18 @@
 class (Monad m, Monad n) => BaseM m n | m -> n where
   -- | Promote a computation from the base monad.
   inBase :: n a -> m a
- 
+
 instance BaseM IO IO        where inBase = id
 instance BaseM Maybe Maybe  where inBase = id
 instance BaseM [] []        where inBase = id
 instance BaseM Id Id        where inBase = id
 instance BaseM Lift Lift    where inBase = id
- 
+
+instance (BaseM m n) => BaseM (IdT          m) n where inBase = lift . inBase
 instance (BaseM m n) => BaseM (ReaderT    i m) n where inBase = lift . inBase
 instance (BaseM m n) => BaseM (StateT     i m) n where inBase = lift . inBase
-instance (BaseM m n,Monoid i) => BaseM (WriterT    i m) n where inBase = lift . inBase
+instance (BaseM m n,Monoid i) =>
+                        BaseM (WriterT    i m) n where inBase = lift . inBase
 instance (BaseM m n) => BaseM (ExceptionT i m) n where inBase = lift . inBase
 instance (BaseM m n) => BaseM (ContT      i m) n where inBase = lift . inBase
 
@@ -164,35 +183,38 @@
   fail x    = error x
   L x >>= k = k x
 
--- For the monad transformers, the definition of 'return' 
+-- For the monad transformers, the definition of 'return'
 -- is completely determined by the 'lift' operations.
 
 -- None of the transformers make essential use of the 'fail' method.
 -- Instead they delegate its behavior to the underlying monad.
 
+instance (Monad m) => Monad (IdT m) where
+  return x    = lift (return x)
+  fail x      = lift (fail x)
+  m >>= k     = IT (runIdT m >>= (runIdT . k))
+
 instance (Monad m) => Monad (ReaderT i m) where
   return x = lift (return x)
   fail x   = lift (fail x)
-  m >>= k  = R $ \r -> runReaderT r m >>= \a -> 
-                       runReaderT r (k a)
+  m >>= k  = R (\r -> runReaderT r m >>= \a -> runReaderT r (k a))
 
 instance (Monad m) => Monad (StateT i m) where
   return x = lift (return x)
   fail x   = lift (fail x)
-  m >>= k  = S $ \s -> runStateT s  m >>= \ ~(a,s') -> 
-                       runStateT s' (k a)
+  m >>= k  = S (\s -> runStateT s m >>= \ ~(a,s') -> runStateT s' (k a))
 
 instance (Monad m,Monoid i) => Monad (WriterT i m) where
   return x = lift (return x)
   fail x   = lift (fail x)
-  m >>= k  = W $ runWriterT m     >>= \ ~(a,w1) -> 
-                 runWriterT (k a) >>= \ ~(b,w2) -> 
+  m >>= k  = W $ runWriterT m     >>= \ ~(a,w1) ->
+                 runWriterT (k a) >>= \ ~(b,w2) ->
                  return (b,mappend w1 w2)
 
 instance (Monad m) => Monad (ExceptionT i m) where
   return x = lift (return x)
   fail x   = lift (fail x)
-  m >>= k  = X $ runExceptionT m >>= \a -> 
+  m >>= k  = X $ runExceptionT m >>= \a ->
                  case a of
                    Left x  -> return (Left x)
                    Right a -> runExceptionT (k a)
@@ -204,6 +226,7 @@
 
 instance                       Functor Id               where fmap = liftM
 instance                       Functor Lift             where fmap = liftM
+instance (Monad m)          => Functor (IdT          m) where fmap = liftM
 instance (Monad m)          => Functor (ReaderT    i m) where fmap = liftM
 instance (Monad m)          => Functor (StateT     i m) where fmap = liftM
 instance (Monad m,Monoid i) => Functor (WriterT    i m) where fmap = liftM
@@ -212,11 +235,11 @@
 
 
 -- $Monadic_Value_Recursion
--- 
+--
 -- Recursion that does not duplicate side-effects.
 -- For details see Levent Erkok's dissertation.
--- 
--- Monadic types built with 'ContT' do not support 
+--
+-- Monadic types built with 'ContT' do not support
 -- monadic value recursion.
 
 instance MonadFix Id where
@@ -225,6 +248,9 @@
 instance MonadFix Lift where
   mfix f  = let m = f (runLift m) in m
 
+instance (MonadFix m) => MonadFix (IdT m) where
+  mfix f  = IT (mfix (runIdT . f))
+
 instance (MonadFix m) => MonadFix (ReaderT i m) where
   mfix f  = R $ \r -> mfix (runReaderT r . f)
 
@@ -241,14 +267,18 @@
 
 
 
+instance (MonadPlus m) => MonadPlus (IdT m) where
+  mzero               = lift mzero
+  mplus (IT m) (IT n) = IT (mplus m n)
+
 instance (MonadPlus m) => MonadPlus (ReaderT i m) where
   mzero             = lift mzero
   mplus (R m) (R n) = R (\r -> mplus (m r) (n r))
- 
+
 instance (MonadPlus m) => MonadPlus (StateT i m) where
   mzero             = lift mzero
   mplus (S m) (S n) = S (\s -> mplus (m s) (n s))
- 
+
 instance (MonadPlus m,Monoid i) => MonadPlus (WriterT i m) where
   mzero             = lift mzero
   mplus (W m) (W n) = W (mplus m n)
@@ -259,7 +289,7 @@
 
 
 -- $Effects
--- 
+--
 -- The following classes define overloaded operations
 -- that can be used to define effectful computations.
 
@@ -272,7 +302,8 @@
 instance (Monad m) => ReaderM (ReaderT i m) i where
   ask = R return
 
-instance (ReaderM m j,Monoid i) 
+instance (ReaderM m j) => ReaderM (IdT          m) j where ask = lift ask
+instance (ReaderM m j,Monoid i)
                        => ReaderM (WriterT    i m) j where ask = lift ask
 instance (ReaderM m j) => ReaderM (StateT     i m) j where ask = lift ask
 instance (ReaderM m j) => ReaderM (ExceptionT i m) j where ask = lift ask
@@ -284,9 +315,10 @@
   -- | Add a value to the collection.
   put  :: i -> m ()
 
-instance (Monad m,Monoid i) => WriterM (WriterT i m) i where 
+instance (Monad m,Monoid i) => WriterM (WriterT i m) i where
   put x = W (return ((),x))
 
+instance (WriterM m j) => WriterM (IdT          m) j where put = lift . put
 instance (WriterM m j) => WriterM (ReaderT    i m) j where put = lift . put
 instance (WriterM m j) => WriterM (StateT     i m) j where put = lift . put
 instance (WriterM m j) => WriterM (ExceptionT i m) j where put = lift . put
@@ -295,7 +327,7 @@
 
 -- | Classifies monads that propagate a state component of type @i@.
 class (Monad m) => StateM m i | m -> i where
-  -- | Get the state. 
+  -- | Get the state.
   get :: m i
   -- | Set the state.
   set :: i -> m ()
@@ -304,9 +336,12 @@
   get   = S (\s -> return (s,s))
   set s = S (\_ -> return ((),s))
 
+instance (StateM m j) => StateM (IdT m) j where
+  get = lift get
+  set = lift . set
 instance (StateM m j) => StateM (ReaderT i m) j where
   get = lift get
-  set = lift . set 
+  set = lift . set
 instance (StateM m j,Monoid i) => StateM (WriterT i m) j where
   get = lift get
   set = lift . set
@@ -320,12 +355,14 @@
 
 -- | Classifies monads that support raising exceptions of type @i@.
 class (Monad m) => ExceptionM m i | m -> i where
-  -- | Raise an exception.  
+  -- | Raise an exception.
   raise :: i -> m a
 
-instance (Monad m) => ExceptionM (ExceptionT i m) i where 
-  raise x = X (return (Left x)) 
+instance (Monad m) => ExceptionM (ExceptionT i m) i where
+  raise x = X (return (Left x))
 
+instance (ExceptionM m j) => ExceptionM (IdT m) j where
+  raise = lift . raise
 instance (ExceptionM m j) => ExceptionM (ReaderT i m) j where
   raise = lift . raise
 instance (ExceptionM m j,Monoid i) => ExceptionM (WriterT i m) j where
@@ -344,6 +381,9 @@
   -- | Capture the current continuation.
   callCC :: ((a -> m b) -> m a) -> m a
 
+instance (ContM m) => ContM (IdT m) where
+  callCC f = IT $ callCC $ \k -> runIdT $ f $ \a -> lift $ k a
+
 instance (ContM m) => ContM (ReaderT i m) where
   callCC f = R $ \r -> callCC $ \k -> runReaderT r $ f $ \a -> lift $ k a
 
@@ -352,10 +392,10 @@
 
 instance (ContM m,Monoid i) => ContM (WriterT i m) where
   callCC f = W $ callCC $ \k -> runWriterT $ f $ \a -> lift $ k (a,mempty)
- 
+
 instance (ContM m) => ContM (ExceptionT i m) where
   callCC f = X $ callCC $ \k -> runExceptionT $ f $ \a -> lift $ k $ Right a
-   
+
 instance (Monad m) => ContM (ContT i m) where
   callCC f = C $ \k -> runContT k $ f $ \a -> C $ \_ -> k a
 
@@ -364,11 +404,9 @@
 --
 -- The following classes define operations that are overloaded
 -- versions of the @run@ operations.   Unlike the @run@ operations,
--- functions do not change the type of the computation (i.e, they
--- do not remove a layer).  However, they do not perform any
--- side-effects in the corresponding layer.  Instead, they execute
--- a computation in a ``separate thread'' with respect to the
--- corresponding effect.  
+-- these functions do not change the type of the computation (i.e, they
+-- do not remove a layer).  Instead, they perform the effects in
+-- a ``separate effect thread''.
 
 -- | Classifies monads that support changing the context for a
 -- sub-computation.
@@ -378,6 +416,9 @@
 
 instance (Monad m)        => RunReaderM (ReaderT    i m) i where
   local i m     = lift (runReaderT i m)
+
+instance (RunReaderM m j) => RunReaderM (IdT m) j where
+  local i (IT m) = IT (local i m)
 instance (RunReaderM m j,Monoid i) => RunReaderM (WriterT i m) j where
   local i (W m) = W (local i m)
 instance (RunReaderM m j) => RunReaderM (StateT     i m) j where
@@ -385,12 +426,15 @@
 instance (RunReaderM m j) => RunReaderM (ExceptionT i m) j where
   local i (X m) = X (local i m)
 
--- | Classifies monads that support collecting the output of 
+-- | Classifies monads that support collecting the output of
 -- a sub-computation.
 class WriterM m i => RunWriterM m i | m -> i where
-  -- | Collect the output from a computation.   
+  -- | Collect the output from a computation.
   collect :: m a -> m (a,i)
 
+instance (RunWriterM m j) => RunWriterM (IdT m) j where
+  collect (IT m) = IT (collect m)
+
 instance (RunWriterM m j) => RunWriterM (ReaderT i m) j where
   collect (R m) = R (collect . m)
 
@@ -404,50 +448,30 @@
 instance (RunWriterM m j) => RunWriterM (ExceptionT i m) j where
   collect (X m) = X (liftM swap (collect m))
     where swap (Right a,w)  = Right (a,w)
-          swap (Left x,_)   = Left x    
+          swap (Left x,_)   = Left x
     -- NOTE: If the local computation fails, then the output
     -- is discarded because the result type cannot accommodate it.
 
 
--- | Classifies monads that support separate state threads.
-class (StateM m i) => RunStateM m i | m -> i where
-  -- | Modify the state for the duration of a computation.
-  -- Returns the final state.
-  runS :: i -> m a -> m (a,i)   
-
-instance (RunStateM m j) => RunStateM (ReaderT i m) j where
-  runS s (R m)  = R (runS s . m)
-
-instance (RunStateM m j,Monoid i) => RunStateM (WriterT i m) j where
-  runS s (W m)  = W (liftM swap (runS s m))
-    where swap (~(a,s),w) = ((a,w),s)
-
-instance (Monad m) => RunStateM (StateT i m) i where
-  runS s m  = lift (runStateT s m)
-
-instance (RunStateM m j) => RunStateM (ExceptionT i m) j where
-  runS s (X m)  = X (liftM swap (runS s m))
-    where swap (Left e,_)   = Left e    
-          swap (Right a,s)  = Right (a,s)
-    -- NOTE: If the local computation fails, then the modifications
-    -- are discarded because the result type cannot accommodate it.
-
 -- | Classifies monads that support handling of exceptions.
 class ExceptionM m i => RunExceptionM m i | m -> i where
   -- | Exceptions are explicit in the result.
-  try :: m a -> m (Either i a)  
+  try :: m a -> m (Either i a)
 
+instance (RunExceptionM m i) => RunExceptionM (IdT m) i where
+  try (IT m) = IT (try m)
+
 instance (RunExceptionM m i) => RunExceptionM (ReaderT j m) i where
   try (R m) = R (try . m)
 
 instance (RunExceptionM m i,Monoid j) => RunExceptionM (WriterT j m) i where
   try (W m) = W (liftM swap (try m))
-    where swap (Right ~(a,w)) = (Right a,w)  
+    where swap (Right ~(a,w)) = (Right a,w)
           swap (Left e)       = (Left e, mempty)
 
 instance (RunExceptionM m i) => RunExceptionM (StateT j m) i where
   try (S m) = S (\s -> liftM (swap s) (try (m s)))
-    where swap _ (Right ~(a,s)) = (Right a,s)  
+    where swap _ (Right ~(a,s)) = (Right a,s)
           swap s (Left e)       = (Left e, s)
 
 instance (Monad m) => RunExceptionM (ExceptionT i m) i where
@@ -459,7 +483,7 @@
 -- | An explicit representation for continuations that store a value.
 newtype Label m a    = Lab ((a, Label m a) -> m ())
 
--- | Capture the current continuation.  
+-- | Capture the current continuation
 -- This function is like 'return', except that it also captures
 -- the current continuation.  Later we can use 'jump' to go back to
 -- the continuation with a possibly different value.
@@ -472,5 +496,69 @@
   where unreachable = error "(bug) jump: unreachable"
 
 
+-- | A isomorphism between (usually) monads.
+-- Typically the constructor and selector of a newtype delcaration.
+data Iso m n = Iso { close :: forall a. m a -> n a,
+                     open  :: forall a. n a -> m a }
 
+-- | Derive the implementation of 'fmap' from 'Functor'.
+derive_fmap :: (Functor m) => Iso m n -> (a -> b) -> n a -> n b
+derive_fmap iso f m = close iso (fmap f (open iso m))
+
+-- | Derive the implementation of 'return' from 'Monad'.
+derive_return :: (Monad m) => Iso m n -> (a -> n a)
+derive_return iso a = close iso (return a)
+
+-- | Derive the implementation of '>>=' from 'Monad'.
+derive_bind :: (Monad m) => Iso m n -> n a -> (a -> n b) -> n b
+derive_bind iso m k = close iso ((open iso m) >>= \x -> open iso (k x))
+
+derive_fail :: (Monad m) => Iso m n -> String -> n a
+derive_fail iso a = close iso (fail a)
+
+-- | Derive the implementation of 'mfix' from 'MonadFix'.
+derive_mfix :: (MonadFix m) => Iso m n -> (a -> n a) -> n a
+derive_mfix iso f = close iso (mfix (open iso . f))
+
+-- | Derive the implementation of 'ask' from 'ReaderM'.
+derive_ask :: (ReaderM m i) => Iso m n -> n i
+derive_ask iso = close iso ask
+
+-- | Derive the implementation of 'put' from 'WriterM'.
+derive_put :: (WriterM m i) => Iso m n -> i -> n ()
+derive_put iso x = close iso (put x)
+
+-- | Derive the implementation of 'get' from 'StateM'.
+derive_get :: (StateM m i) => Iso m n -> n i
+derive_get iso = close iso get
+
+-- | Derive the implementation of 'set' from 'StateM'.
+derive_set :: (StateM m i) => Iso m n -> i -> n ()
+derive_set iso x = close iso (set x)
+
+-- | Derive the implementation of 'raise' from 'ExceptionM'.
+derive_raise :: (ExceptionM m i) => Iso m n -> i -> n a
+derive_raise iso x = close iso (raise x)
+
+-- | Derive the implementation of 'callCC' from 'ContM'.
+derive_callCC :: (ContM m) => Iso m n -> ((a -> n b) -> n a) -> n a
+derive_callCC iso f = close iso (callCC (open iso . f . (close iso .)))
+
+-- | Derive the implementation of 'local' from 'RunReaderM'.
+derive_local :: (RunReaderM m i) => Iso m n -> i -> n a -> n a
+derive_local iso i = close iso . local i . open iso
+
+-- | Derive the implementation of 'collect' from 'RunWriterM'.
+derive_collect :: (RunWriterM m i) => Iso m n -> n a -> n (a,i)
+derive_collect iso = close iso . collect . open iso
+
+-- | Derive the implementation of 'try' from 'RunExceptionM'.
+derive_try :: (RunExceptionM m i) => Iso m n -> n a -> n (Either i a)
+derive_try iso = close iso . try . open iso
+
+derive_lift :: (MonadT t, Monad m) => Iso (t m) n -> m a -> n a
+derive_lift iso m = close iso (lift m)
+
+derive_inBase :: (BaseM m x) => Iso m n -> x a -> n a
+derive_inBase iso m = close iso (inBase m)
 
diff --git a/src/Monads.hs b/src/Monads.hs
--- a/src/Monads.hs
+++ b/src/Monads.hs
@@ -22,6 +22,12 @@
 newtype Exception i a     = X' { unX :: ExceptionT  i Id a }
 newtype Cont      i a     = C' { unC :: ContT       i Id a }
 
+iso_R = Iso R' unR
+iso_W = Iso W' unW
+iso_S = Iso S' unS
+iso_X = Iso X' unX
+iso_C = Iso C' unC
+
 instance               BaseM (Reader    i) (Reader    i) where inBase = id
 instance (Monoid i) => BaseM (Writer    i) (Writer    i) where inBase = id
 instance               BaseM (State     i) (State     i) where inBase = id
@@ -29,46 +35,46 @@
 instance               BaseM (Cont      i) (Cont      i) where inBase = id
 
 instance Monad (Reader i) where
-  return x    = R' (return x)
-  fail x      = R' (fail x)
-  m >>= f     = R' (unR m >>= (unR . f))
+  return  = derive_return iso_R
+  fail    = derive_fail iso_R
+  (>>=)   = derive_bind iso_R
 
 instance (Monoid i) => Monad (Writer i) where
-  return x    = W' (return x)
-  fail x      = W' (fail x)
-  m >>= f     = W' (unW m >>= (unW . f))
+  return  = derive_return iso_W
+  fail    = derive_fail iso_W
+  (>>=)   = derive_bind iso_W
 
 instance Monad (State i) where
-  return x    = S' (return x)
-  fail x      = S' (fail x)
-  m >>= f     = S' (unS m >>= (unS . f))
+  return  = derive_return iso_S
+  fail    = derive_fail iso_S
+  (>>=)   = derive_bind iso_S
 
 instance Monad (Exception i) where
-  return x    = X' (return x)
-  fail x      = X' (fail x)
-  m >>= f     = X' (unX m >>= (unX . f))
+  return  = derive_return iso_X
+  fail    = derive_fail iso_X
+  (>>=)   = derive_bind iso_X
 
 instance Monad (Cont i) where
-  return x    = C' (return x)
-  fail x      = C' (fail x)
-  m >>= f     = C' (unC m >>= (unC . f))
+  return  = derive_return iso_C
+  fail    = derive_fail iso_C
+  (>>=)   = derive_bind iso_C
 
-instance               Functor (Reader    i) where fmap = liftM
-instance (Monoid i) => Functor (Writer    i) where fmap = liftM
-instance               Functor (State     i) where fmap = liftM
-instance               Functor (Exception i) where fmap = liftM
-instance               Functor (Cont      i) where fmap = liftM
+instance               Functor (Reader    i) where fmap = derive_fmap iso_R
+instance (Monoid i) => Functor (Writer    i) where fmap = derive_fmap iso_W
+instance               Functor (State     i) where fmap = derive_fmap iso_S
+instance               Functor (Exception i) where fmap = derive_fmap iso_X
+instance               Functor (Cont      i) where fmap = derive_fmap iso_C
 
-instance               MonadFix (Reader    i) where mfix f = R' (mfix (unR . f))
-instance (Monoid i) => MonadFix (Writer    i) where mfix f = W' (mfix (unW . f))
-instance               MonadFix (State     i) where mfix f = S' (mfix (unS . f))
-instance               MonadFix (Exception i) where mfix f = X' (mfix (unX . f))
+instance               MonadFix (Reader    i) where mfix = derive_mfix iso_R
+instance (Monoid i) => MonadFix (Writer    i) where mfix = derive_mfix iso_W
+instance               MonadFix (State     i) where mfix = derive_mfix iso_S
+instance               MonadFix (Exception i) where mfix = derive_mfix iso_X
 
-instance ReaderM (Reader i) i where ask = R' ask
-instance (Monoid i) => WriterM (Writer i) i where put = W' . put 
-instance StateM (State i) i where get = S' get; set = S' . set 
-instance ExceptionM (Exception i) i where raise = X' . raise 
-instance ContM (Cont i) where callCC f = C' (callCC (unC . f . (C' .)))
+instance ReaderM (Reader i) i where ask = derive_ask iso_R
+instance (Monoid i) => WriterM (Writer i) i where put = derive_put iso_W
+instance StateM (State i) i where get = derive_get iso_S; set = derive_set iso_S
+instance ExceptionM (Exception i) i where raise = derive_raise iso_X
+instance ContM (Cont i) where callCC = derive_callCC iso_C
 
 runReader     :: i -> Reader i a -> a
 runWriter     :: Writer i a -> (a,i)
@@ -76,17 +82,20 @@
 runException  :: Exception i a -> Either i a
 runCont       :: (a -> i) -> Cont i a -> i
 
-runReader i  = runId . runReaderT i          . unR 
+runReader i  = runId . runReaderT i          . unR
 runWriter    = runId . runWriterT            . unW
 runState  i  = runId . runStateT i           . unS
 runException = runId . runExceptionT         . unX
-runCont   i  = runId . runContT (return . i) . unC 
+runCont   i  = runId . runContT (return . i) . unC
 
-instance RunReaderM (Reader i) i where local i = R' . local i . unR
-instance RunStateM (State i) i where runS i  = S' . runS i  . unS
+instance RunReaderM (Reader i) i where
+  local = derive_local iso_R
+
 instance (Monoid i) => RunWriterM (Writer i) i where
-  collect = W' . collect . unW
-instance RunExceptionM (Exception i) i where try = X' . try     . unX
+  collect = derive_collect iso_W
+
+instance RunExceptionM (Exception i) i where
+  try = derive_try iso_X
 
 
 
