diff --git a/monadLib.cabal b/monadLib.cabal
--- a/monadLib.cabal
+++ b/monadLib.cabal
@@ -1,22 +1,44 @@
 Name:           monadLib
-Version:        3.5.1
+Version:        3.5.2
 License:        BSD3
 License-file:   LICENSE
 Author:         Iavor S. Diatchki
 Maintainer:     diatchki@galois.com
-Homepage:       http://www.purely-functional.net/monadLib
+Homepage:       http://wiki.github.com/yav/monadlib
 Category:       Monads
 Synopsis:       A collection of monad transformers.
 Description:    A collection of monad transformers.
-hs-source-dirs: src
-Build-Depends:  base < 4
 Build-type:     Simple
-Extra-source-files: LICENSE, README, CHANGES
-Exposed-modules: MonadLib, MonadLib.Monads, MonadLib.Derive
+Cabal-version: >= 1.2
+Extra-source-files:
+  LICENSE,
+  README,
+  CHANGES
 
+Flag base3
+  Description: Build for compatability with base3
+  Default:     False
 
-Extensions:
-  MultiParamTypeClasses, FunctionalDependencies, Rank2Types,
-  UndecidableInstances
-GHC-options:    -O2 -W
+Library
+  hs-source-dirs: src
+  Exposed-modules:
+    MonadLib,
+    MonadLib.Monads,
+    MonadLib.Derive
+  Extensions:
+    CPP,
+    MultiParamTypeClasses,
+    FunctionalDependencies,
+    Rank2Types,
+    FlexibleInstances,
+    UndecidableInstances
+
+  if flag(base3)
+    Build-depends: base < 4
+    CPP-options: -DUSE_BASE3
+  else
+    Build-depends: base >= 4 && < 5
+
+  GHC-options:    -O2 -Wall
+
 
diff --git a/src/MonadLib.hs b/src/MonadLib.hs
--- a/src/MonadLib.hs
+++ b/src/MonadLib.hs
@@ -1,4 +1,3 @@
-{-# OPTIONS_GHC -fglasgow-exts -fallow-undecidable-instances #-}
 {-| This library provides a collection of monad transformers that
     can be combined to produce various monads.
 -}
@@ -34,6 +33,11 @@
   -- $Nested_Exec
   RunReaderM(..), RunWriterM(..), RunExceptionM(..),
 
+  -- * Utility functions
+  asks, puts, sets, sets_, raises,
+  mapReader, mapWriter, mapException,
+  handle,
+
   -- * Miscellaneous
   version,
   module Control.Monad
@@ -44,14 +48,19 @@
 import Control.Monad
 import Control.Monad.Fix
 import Control.Monad.ST (ST)
-import qualified Control.Exception as IO (throwIO,try,Exception)
+import qualified Control.Exception as IO (throwIO,try)
+#ifdef USE_BASE3
+import qualified Control.Exception as IO (Exception)
+#else
+import qualified Control.Exception as IO (SomeException)
+#endif
 import System.Exit(ExitCode,exitWith)
 import Data.Monoid
 import Prelude hiding (Ordering(..))
 
 -- | The current version of the library.
 version :: (Int,Int,Int)
-version = (3,4,4)
+version = (3,5,2)
 
 
 -- $Types
@@ -182,31 +191,23 @@
 -- utilize the effect.
 
 
+class MonadT t where
+  -- | Promote a computation from the underlying monad.
+  lift :: (Monad m) => m a -> t m a
+
 -- Notes:
 --   * It is interesting to note that these use something the resembles
 --     the non-transformer 'return's.
 --   * These are more general then the lift in the MonadT class because
 --     most of them can lift arbitrary functors (some, even arbitrary type ctrs)
-lift_IdT m          = IT m
-lift_ReaderT m      = R (\_ -> m)
-lift_StateT f m     = S (\s -> f (\a -> (a,s)) m)
-lift_WriterT f m    = W (f (\a -> P a mempty) m)
-lift_ExceptionT f m = X (f Right m)
-lift_ChoiceT f m    = ChoiceEff (f Answer m)
-lift_ContT f m      = C (f m)
-
-class MonadT t where
-  -- | Promote a computation from the underlying monad.
-  lift :: (Monad m) => m a -> t m a
-
-instance MonadT IdT            where lift = lift_IdT
-instance MonadT (ReaderT    i) where lift = lift_ReaderT
-instance MonadT (StateT     i) where lift = lift_StateT liftM
+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)
-      => MonadT (WriterT i)    where lift = lift_WriterT liftM
-instance MonadT (ExceptionT i) where lift = lift_ExceptionT liftM
-instance MonadT ChoiceT        where lift = lift_ChoiceT liftM
-instance MonadT (ContT      i) where lift = lift_ContT (>>=)
+      => MonadT (WriterT i)    where lift m = W (liftM (\a -> P a mempty) m)
+instance MonadT (ExceptionT i) where lift m = X (liftM Right m)
+instance MonadT ChoiceT        where lift m = ChoiceEff (liftM Answer m)
+instance MonadT (ContT      i) where lift m = C (\k -> m >>= k)
 
 
 -- Definitions for some of the methods that are the same for all transformers
@@ -501,8 +502,13 @@
   -- | Raise an exception.
   raise :: i -> m a
 
+#ifdef USE_BASE3
 instance ExceptionM IO IO.Exception where
   raise = IO.throwIO
+#else
+instance ExceptionM IO IO.SomeException where
+  raise = IO.throwIO
+#endif
 
 instance (Monad m) => ExceptionM (ExceptionT i m) i where
   raise x = X (return (Left x))
@@ -620,8 +626,13 @@
   -- successful computations are tagged with "Right".
   try :: m a -> m (Either i a)
 
+#ifdef USE_BASE3
 instance RunExceptionM IO IO.Exception where
   try = IO.try
+#else
+instance RunExceptionM IO IO.SomeException where
+  try = IO.try
+#endif
 
 instance (Monad m) => RunExceptionM (ExceptionT i m) i where
   try m = lift (runExceptionT m)
@@ -677,4 +688,64 @@
 jump               :: (ContM m) => a -> Label m a -> m b
 jump x (Lab k)      = k (x, Lab k) >> return unreachable
   where unreachable = error "(bug) jump: unreachable"
+
+
+--------------------------------------------------------------------------------
+
+-- | Apply a function to the environment.
+-- Useful for accessing environmnt components.
+asks :: ReaderM m r => (r -> a) -> m a
+asks f      = do r <- ask
+                 return (f r)
+
+-- | Add content the output and return a result.
+puts :: WriterM m w => (a,w) -> m a
+puts ~(a,w) = put w >> return a
+
+-- | Update the state and return a result.
+sets :: StateM m s => (s -> (a,s)) -> m a
+sets f      = do s <- get
+                 let (a,s1) = f s
+                 set s1
+                 return a
+
+-- | Updates the state with the given function.
+sets_ :: StateM m s => (s -> s) -> m ()
+sets_ f     = do s <- get
+                 set (f s)
+-- | Either raise an exception or return a value.
+-- 'Left' values signify the we should raise an exception,
+-- 'Right' values indicate success.
+raises :: ExceptionM m x => Either x a -> m a
+raises (Right a)  = return a
+raises (Left x)   = raise x
+
+-- for ChoiceT we already have "msum"
+-- for ContT, not sure if it makes sense.
+
+-- | Modify the environment for the duration of a computation.
+mapReader        :: RunReaderM m r => (r -> r) -> m a -> m a
+mapReader f m     = do r <- ask
+                       local (f r) m
+
+-- | Modify the output of a computation.
+mapWriter        :: RunWriterM m w => (w -> w) -> m a -> m a
+mapWriter f m     = do ~(a,w) <- collect m
+                       put (f w)
+                       return a
+
+-- | Modify the exception that was risen by a computation.
+mapException     :: RunExceptionM m x => (x -> x) -> m a -> m a
+mapException f m  = do r <- try m
+                       case r of
+                         Right a -> return a
+                         Left x  -> raise (f x)
+
+-- | Apply the given exception handler, if a computation raises an exception.
+handle           :: RunExceptionM m x => m a -> (x -> m a) -> m a
+handle m f        = do r <- try m
+                       case r of
+                         Right a -> return a
+                         Left x  -> f x
+
 
diff --git a/src/MonadLib/Derive.hs b/src/MonadLib/Derive.hs
--- a/src/MonadLib/Derive.hs
+++ b/src/MonadLib/Derive.hs
@@ -1,4 +1,3 @@
-{-# OPTIONS_GHC -fglasgow-exts -fallow-undecidable-instances #-}
 {-| This module defines a number of functions that make it easy
 to get the functionality of MonadLib for user-defined newtypes.
 -}
diff --git a/src/MonadLib/Monads.hs b/src/MonadLib/Monads.hs
--- a/src/MonadLib/Monads.hs
+++ b/src/MonadLib/Monads.hs
@@ -1,4 +1,3 @@
-{-# OPTIONS_GHC -fglasgow-exts -fallow-undecidable-instances #-}
 {-|  This module contains a collection of monads that
    are defined in terms of the monad transformers from
    "MonadLib".   The definitions in this module are
@@ -22,6 +21,12 @@
 newtype State     i a = S' { unS :: StateT     i Id a }
 newtype Exception i a = X' { unX :: ExceptionT i Id a }
 newtype Cont      i a = C' { unC :: ContT      i Id a }
+
+iso_R :: Iso (ReaderT i Id) (Reader i)
+iso_W :: Iso (WriterT i Id) (Writer i)
+iso_S :: Iso (StateT i Id) (State i)
+iso_X :: Iso (ExceptionT i Id) (Exception i)
+iso_C :: Iso (ContT i Id) (Cont i)
 
 iso_R = Iso R' unR
 iso_W = Iso W' unW
