diff --git a/CHANGES b/CHANGES
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,10 @@
+Version 3.0
+  * Add instane from `MonadFail`---none of the transformers implement this
+    functionality so the implementation just lifts things.
+
+Version 3.8
+  * Added `WithBase`
+
 Version 3.3.0
 
 * Remove 'RunStateM'
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,7 +1,6 @@
-Copyright (c) 2006 Iavor S. Diatchki
+Copyright 2006 Iavor S. Diatchki
 
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
 
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/monadLib.cabal b/monadLib.cabal
--- a/monadLib.cabal
+++ b/monadLib.cabal
@@ -1,43 +1,30 @@
+cabal-version:  3.0
 Name:           monadLib
-Version:        3.5.2
-License:        BSD3
+Version:        3.10.3
+License:        ISC
 License-file:   LICENSE
 Author:         Iavor S. Diatchki
 Maintainer:     diatchki@galois.com
-Homepage:       http://wiki.github.com/yav/monadlib
+Homepage:       https://github.com/yav/monadlib
 Category:       Monads
 Synopsis:       A collection of monad transformers.
 Description:    A collection of monad transformers.
 Build-type:     Simple
-Cabal-version: >= 1.2
 Extra-source-files:
   LICENSE,
   README,
   CHANGES
 
-Flag base3
-  Description: Build for compatability with base3
-  Default:     False
 
 Library
+  default-language: Haskell2010
   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
+  Build-depends: base >= 4.9 && < 5
 
   GHC-options:    -O2 -Wall
 
diff --git a/src/MonadLib.hs b/src/MonadLib.hs
--- a/src/MonadLib.hs
+++ b/src/MonadLib.hs
@@ -1,3 +1,9 @@
+{-# LANGUAGE CPP, MultiParamTypeClasses, FunctionalDependencies,
+             UndecidableInstances, FlexibleInstances, FlexibleContexts #-}
+{-# LANGUAGE DataKinds, TypeFamilies, TypeOperators #-}
+{-# LANGUAGE Rank2Types #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE Safe #-}
 {-| This library provides a collection of monad transformers that
     can be combined to produce various monads.
 -}
@@ -18,7 +24,7 @@
   -- * Effect Classes
   -- $Effects
   ReaderM(..), WriterM(..), StateM(..), ExceptionM(..), ContM(..), AbortM(..),
-  Label, labelCC, jump,
+  Label, labelCC, labelCC_, jump, labelC, callCC,
 
   -- * Execution
 
@@ -28,6 +34,7 @@
   runIdT, runReaderT, runWriterT,
   runStateT, runExceptionT, runContT,
   runChoiceT, findOne, findAll,
+  RunM(..),
 
   -- ** Nested Execution
   -- $Nested_Exec
@@ -37,30 +44,20 @@
   asks, puts, sets, sets_, raises,
   mapReader, mapWriter, mapException,
   handle,
+  WithBase,
 
-  -- * Miscellaneous
-  version,
   module Control.Monad
 ) where
 
-
 import Control.Applicative
 import Control.Monad
 import Control.Monad.Fix
 import Control.Monad.ST (ST)
-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 qualified Control.Exception as IO (throwIO,try,SomeException)
 import System.Exit(ExitCode,exitWith)
-import Data.Monoid
+import Data.Kind(Type)
 import Prelude hiding (Ordering(..))
-
--- | The current version of the library.
-version :: (Int,Int,Int)
-version = (3,5,2)
+import qualified Control.Monad.Fail as MF
 
 
 -- $Types
@@ -181,7 +178,41 @@
 runContT i (C m) = m i
 
 
+-- | Generalized running.
+class Monad m => RunM m a r | m a -> r where
+  runM :: m a -> r
 
+instance RunM Id a a where
+  runM = runId
+
+instance RunM Lift a a where
+  runM = runLift
+
+instance RunM IO a (IO a) where
+  runM = id
+
+instance RunM m a r => RunM (IdT m) a r where
+  runM = runM . runIdT
+
+instance RunM m a r => RunM (ReaderT i m) a (i -> r) where
+  runM m i = runM (runReaderT i m)
+
+instance (Monoid i, RunM m (a,i) r) => RunM (WriterT i m) a r where
+  runM = runM . runWriterT
+
+instance RunM m (a,i) r => RunM (StateT i m) a (i -> r) where
+  runM m i = runM (runStateT i m)
+
+instance RunM m (Either i a) r => RunM (ExceptionT i m) a r where
+  runM = runM . runExceptionT
+
+instance RunM m i r => RunM (ContT i m) a ((a -> m i) -> r) where
+  runM m k = runM (runContT k m)
+
+instance RunM m (Maybe (a,ChoiceT m a)) r => RunM (ChoiceT m) a r where
+  runM = runM . runChoiceT
+
+
 -- $Lifting
 --
 -- The following operations allow us to promote computations
@@ -218,9 +249,14 @@
 t_return   :: (MonadT t, Monad m) => a -> t m a
 t_return x  = lift (return x)
 
-t_fail     :: (MonadT t, Monad m) => String -> t m a
-t_fail x    = lift (fail x)
+t_fail     :: (MonadT t, MF.MonadFail m) => String -> t m a
+t_fail x    = lift (MF.fail x)
 
+#if !MIN_VERSION_base(4,11,0)
+t_oldfail  :: (MonadT t, Monad m) => String -> t m a
+t_oldfail x = lift (fail x)
+#endif
+
 t_mzero    :: (MonadT t, MonadPlus m) => t m a
 t_mzero     = lift mzero
 
@@ -267,64 +303,82 @@
 
 
 instance Monad Id where
-  return x = I x
-  fail x   = error x
   m >>= k  = k (runId m)
 
+#if !MIN_VERSION_base(4,11,0)
+  fail = error
+#endif
+
 instance Monad Lift where
-  return x  = L x
-  fail x    = error x
   L x >>= k = k x     -- Note: the pattern is important here
                       -- because it makes things strict
 
+#if !MIN_VERSION_base(4,11,0)
+  fail = error
+#endif
 
+
 -- Note: 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  = t_return
-  fail    = t_fail
   m >>= k = IT (runIdT m >>= (runIdT . k))
 
+#if !MIN_VERSION_base(4,11,0)
+  fail = t_oldfail
+#endif
+
 instance (Monad m) => Monad (ReaderT i m) where
-  return  = t_return
-  fail    = t_fail
   m >>= k = R (\r -> runReaderT r m >>= \a -> runReaderT r (k a))
 
+#if !MIN_VERSION_base(4,11,0)
+  fail = t_oldfail
+#endif
+
 instance (Monad m) => Monad (StateT i m) where
-  return  = t_return
-  fail    = t_fail
   m >>= k = S (\s -> runStateT s m >>= \ ~(a,s') -> runStateT s' (k a))
 
+#if !MIN_VERSION_base(4,11,0)
+  fail = t_oldfail
+#endif
+
 instance (Monad m,Monoid i) => Monad (WriterT i m) where
-  return  = t_return
-  fail    = t_fail
   m >>= k = W $ unW m     >>= \ ~(P a w1) ->
                 unW (k a) >>= \ ~(P b w2) ->
                 return (P b (mappend w1 w2))
 
+#if !MIN_VERSION_base(4,11,0)
+  fail = t_oldfail
+#endif
+
 instance (Monad m) => Monad (ExceptionT i m) where
-  return  = t_return
-  fail    = t_fail
   m >>= k = X $ runExceptionT m >>= \e ->
                 case e of
                   Left x  -> return (Left x)
                   Right a -> runExceptionT (k a)
 
+#if !MIN_VERSION_base(4,11,0)
+  fail = t_oldfail
+#endif
+
 instance (Monad m) => Monad (ChoiceT m) where
-  return x  = Answer x
-  fail x    = lift (fail x)
 
   Answer a  >>= k     = k a
   NoAnswer >>= _      = NoAnswer
   Choice m1 m2 >>= k  = Choice (m1 >>= k) (m2 >>= k)
   ChoiceEff m >>= k   = ChoiceEff (liftM (>>= k) m)
 
+#if !MIN_VERSION_base(4,11,0)
+  fail = t_oldfail
+#endif
+
 instance (Monad m) => Monad (ContT i m) where
-  return  = t_return
-  fail    = t_fail
   m >>= k = C $ \c -> runContT (\a -> runContT c (k a)) m
 
+#if !MIN_VERSION_base(4,11,0)
+  fail = t_oldfail
+#endif
+
 instance                       Functor Id               where fmap = liftM
 instance                       Functor Lift             where fmap = liftM
 instance (Monad m)          => Functor (IdT          m) where fmap = liftM
@@ -340,17 +394,17 @@
 -- NOTE: It may be possible to make these more general
 -- (i.e., have Applicative, or even Functor transformers)
 
-instance              Applicative Id            where (<*>) = ap; pure = return
-instance              Applicative Lift          where (<*>) = ap; pure = return
-instance (Monad m) => Applicative (IdT m)       where (<*>) = ap; pure = return
-instance (Monad m) => Applicative (ReaderT i m) where (<*>) = ap; pure = return
-instance (Monad m) => Applicative (StateT i m)  where (<*>) = ap; pure = return
+instance              Applicative Id            where (<*>) = ap; pure x = I x
+instance              Applicative Lift          where (<*>) = ap; pure x = L x
+instance (Monad m) => Applicative (IdT m)       where (<*>) = ap; pure = t_return
+instance (Monad m) => Applicative (ReaderT i m) where (<*>) = ap; pure = t_return
+instance (Monad m) => Applicative (StateT i m)  where (<*>) = ap; pure = t_return
 instance (Monad m,Monoid i)
-                   => Applicative (WriterT i m) where (<*>) = ap; pure = return
+                   => Applicative (WriterT i m) where (<*>) = ap; pure = t_return
 instance (Monad m) => Applicative (ExceptionT i m)
-                                                where (<*>) = ap; pure = return
-instance (Monad m) => Applicative (ChoiceT m)   where (<*>) = ap; pure = return
-instance (Monad m) => Applicative (ContT i m)   where (<*>) = ap; pure = return
+                                                where (<*>) = ap; pure = t_return
+instance (Monad m) => Applicative (ChoiceT m)   where (<*>) = ap; pure = Answer
+instance (Monad m) => Applicative (ContT i m)   where (<*>) = ap; pure = t_return
 
 instance (MonadPlus m)
            => Alternative (IdT m)           where (<|>) = mplus; empty = mzero
@@ -533,29 +587,39 @@
 -- | Classifies monads that provide access to a computation's continuation.
 class Monad m => ContM m where
   -- | Capture the current continuation.
-  callCC :: ((a -> m b) -> m a) -> m a
+  callWithCC :: ((a -> Label m) -> m a) -> m a
 
+
+-- This captures a common pattern in the lifted definitions of `callWithCC`.
+liftJump :: (ContM m, MonadT t) =>
+  (a -> b) ->
+  ((a -> Label (t m)) -> t m a) ->
+  ((b -> Label    m ) -> t m a)
+liftJump ans f l = f $ \a -> Lab (lift $ jump $ l $ ans a)
+
+
 instance (ContM m) => ContM (IdT m) where
-  callCC f = IT $ callCC $ \k -> runIdT $ f $ \a -> lift $ k a
+  callWithCC f = IT $ callWithCC $ \k -> runIdT $ liftJump id f k
 
 instance (ContM m) => ContM (ReaderT i m) where
-  callCC f = R $ \r -> callCC $ \k -> runReaderT r $ f $ \a -> lift $ k a
+  callWithCC f = R $ \r -> callWithCC $ \k -> runReaderT r $ liftJump id f k
 
 instance (ContM m) => ContM (StateT i m) where
-  callCC f = S $ \s -> callCC $ \k -> runStateT s $ f $ \a -> lift $ k (a,s)
+  callWithCC f = S $ \s -> callWithCC $ \k -> runStateT s $ liftJump (ans s) f k
+    where ans s a = (a,s)
 
 instance (ContM m,Monoid i) => ContM (WriterT i m) where
-  callCC f = W $ callCC $ \k -> unW $ f $ \a -> lift $ k (P a mempty)
+  callWithCC f = W $ callWithCC $ \k -> unW $ liftJump (`P` mempty) f k
 
 instance (ContM m) => ContM (ExceptionT i m) where
-  callCC f = X $ callCC $ \k -> runExceptionT $ f $ \a -> lift $ k $ Right a
+  callWithCC f = X $ callWithCC $ \k -> runExceptionT $ liftJump Right f k
 
 instance (ContM m) => ContM (ChoiceT m) where
-  callCC f = ChoiceEff $ callCC $ \k -> return $ f $ \a -> lift $ k $ Answer a
+  callWithCC f = ChoiceEff $ callWithCC $ \k -> return $ liftJump Answer f k
     -- ??? What does this do ???
 
 instance (Monad m) => ContM (ContT i m) where
-  callCC f = C $ \k -> runContT k $ f $ \a -> C $ \_ -> k a
+  callWithCC f = C $ \k -> runContT k $ f $ \a -> Lab (C $ \_ -> k a)
 
 -- $Nested_Exec
 --
@@ -584,6 +648,9 @@
 instance (RunReaderM m j) => RunReaderM (ExceptionT i m) j where
   local i (X m) = X (local i m)
 
+instance (RunReaderM m j) => RunReaderM (ContT i m) j where
+  local i (C m) = C (local i . m)
+
 -- | Classifies monads that support collecting the output of
 -- a sub-computation.
 class WriterM m i => RunWriterM m i | m -> i where
@@ -604,7 +671,11 @@
   collect (X m) = X (liftM swap (collect m))
     where swap (Right a,w)  = Right (a,w)
           swap (Left x,_)   = Left x
+instance (RunWriterM m j, MonadFix m) => RunWriterM (ContT i m) j where
+  collect (C m) = C $ \k -> fst `liftM`
+                                mfix (\ ~(_,w) -> collect (m (\a -> k (a,w))))
 
+
 -- $WriterM_ExceptionT
 --
 -- About the 'WriterM' instance:
@@ -626,13 +697,8 @@
   -- 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)
@@ -674,22 +740,40 @@
 --------------------------------------------------------------------------------
 -- Some convenient functions for working with continuations.
 
--- | An explicit representation for continuations that store a value.
-newtype Label m a    = Lab ((a, Label m a) -> m ())
+-- | An explicit representation for monadic continuations.
+newtype Label m     = Lab (forall b. m b)
 
 -- | Capture the current continuation.
 -- This function is like 'return', except that it also captures
 -- the current continuation.  Later, we can use 'jump' to repeat the
 -- computation from this point onwards but with a possibly different value.
-labelCC            :: (ContM m) => a -> m (a, Label m a)
-labelCC x           = callCC (\k -> return (x, Lab k))
+labelCC            :: (ContM m) => a -> m (a, a -> Label m)
+labelCC x           = callWithCC (\l -> let label a = Lab (jump (l (a, label)))
+                                        in return (x, label))
 
--- | Change the value passed to a previously captured continuation.
-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"
+-- | Capture the current continuation.
+-- Later we can use `jump` to restart the program from this point.
+labelCC_           :: forall m. (ContM m) => m (Label m)
+labelCC_            = callWithCC $ \k -> let x :: m a   -- Signature matters!!!
+                                             x = jump (k (Lab x))
+                                         in x
 
+-- | A version of `callWithCC` that avoids the need for an explicit
+-- use of the `jump` function.
+callCC             :: ContM m => ((a -> m b) -> m a) -> m a
+callCC f            = callWithCC $ \l -> f $ \a -> jump $ l a
 
+-- | Label a given continuation.
+labelC             :: (forall b. m b) -> Label m
+labelC k            = Lab k
+
+-- | Restart a previously captured computation.
+jump               :: Label m -> m a
+jump (Lab k)       = k
+
+
+
+
 --------------------------------------------------------------------------------
 
 -- | Apply a function to the environment.
@@ -749,3 +833,38 @@
                          Left x  -> f x
 
 
+{- | A convenience type family for defining stacks of monads.
+The first entry in the list is the top-most layer of the monad stack
+(i.e., the one that is furtherest from the base).  For example:
+
+> newtype M a = M { unM ::
+>   WithBase IO
+>     '[ ReaderT    Int
+>      , StateT     Char
+>      , ExceptionT String
+>      ] a
+>   }
+
+is equivalent to:
+
+> newtype M a = M { unM ::
+>   ReaderT    Int      (
+>   StateT     Char     (
+>   ExceptionT String
+>   IO                  )) a
+>   }
+
+-}
+type family WithBase base layers :: Type -> Type where
+  WithBase b '[]        = b
+  WithBase b (f ': fs)  = f (WithBase b fs)
+
+
+instance MF.MonadFail m => MF.MonadFail (IdT          m) where fail = t_fail
+instance MF.MonadFail m => MF.MonadFail (ReaderT    i m) where fail = t_fail
+instance (Monoid i, MF.MonadFail m)
+                        => MF.MonadFail (WriterT    i m) where fail = t_fail
+instance MF.MonadFail m => MF.MonadFail (StateT     i m) where fail = t_fail
+instance MF.MonadFail m => MF.MonadFail (ExceptionT i m) where fail = t_fail
+instance MF.MonadFail m => MF.MonadFail (ChoiceT      m) where fail = t_fail
+instance MF.MonadFail m => MF.MonadFail (ContT      i m) where fail = t_fail
diff --git a/src/MonadLib/Derive.hs b/src/MonadLib/Derive.hs
--- a/src/MonadLib/Derive.hs
+++ b/src/MonadLib/Derive.hs
@@ -1,20 +1,38 @@
+{-# LANGUAGE Rank2Types #-}
+{-# LANGUAGE Safe #-}
+
 {-| This module defines a number of functions that make it easy
 to get the functionality of MonadLib for user-defined newtypes.
 -}
 module MonadLib.Derive (
-  Iso(Iso), derive_fmap, derive_return, derive_bind, derive_fail, derive_mfix,
-  derive_ask, derive_put, derive_get, derive_set, derive_raise, derive_callCC,
-  derive_abort,
-  derive_local, derive_collect, derive_try,
+  Iso(Iso),
+  derive_fmap,
+  derive_pure, derive_apply,
+  derive_empty, derive_or,
+  derive_return, derive_bind, derive_fail,
   derive_mzero, derive_mplus,
-  derive_lift, derive_inBase,
+  derive_mfix,
+  derive_ask,
+  derive_local,
+  derive_put,
+  derive_collect,
+  derive_get,
+  derive_set,
+  derive_raise,
+  derive_try,
+  derive_callWithCC,
+  derive_abort,
+  derive_lift,
+  derive_inBase,
+  derive_runM,
 ) where
 
 
 import MonadLib
-import Control.Monad
+import Control.Applicative
 import Control.Monad.Fix
 import Prelude hiding (Ordering(..))
+import Control.Monad.Fail as MF
 
 -- | An isomorphism between (usually) monads.
 -- Typically the constructor and selector of a newtype delcaration.
@@ -25,6 +43,22 @@
 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 'pure' from 'Applicative'.
+derive_pure :: (Applicative m) => Iso m n -> a -> n a
+derive_pure iso a = close iso (pure a)
+
+-- | Derive the implementation of '<*>' from 'Applicative'.
+derive_apply :: (Applicative m) => Iso m n -> n (a -> b) -> (n a -> n b)
+derive_apply iso f x = close iso (open iso f <*> open iso x)
+
+-- | Derive the implementation of 'empty' from 'Alternative'.
+derive_empty :: (Alternative m) => Iso m n -> n a
+derive_empty iso = close iso empty
+
+-- | Derive the implementation of '<|>' from 'Alternative'.
+derive_or :: (Alternative m) => Iso m n -> n a -> n a -> n a
+derive_or iso a b = close iso (open iso a <|> open iso b)
+
 -- | 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)
@@ -33,8 +67,8 @@
 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_fail :: (MF.MonadFail m) => Iso m n -> String -> n a
+derive_fail iso a = close iso (MF.fail a)
 
 -- | Derive the implementation of 'mfix' from 'MonadFix'.
 derive_mfix :: (MonadFix m) => Iso m n -> (a -> n a) -> n a
@@ -60,9 +94,10 @@
 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 'callWithCC' from 'ContM'.
+derive_callWithCC :: (ContM m) => Iso m n -> ((a -> Label n) -> n a) -> n a
+derive_callWithCC iso f = close iso $ callWithCC $ open iso . f . relab
+  where relab k a = labelC (close iso $ jump $ k a)
 
 derive_abort :: (AbortM m i) => Iso m n -> i -> n a
 derive_abort iso i = close iso (abort i)
@@ -94,3 +129,7 @@
 -- | Derive the implementation of 'inBase' from 'BaseM'.
 derive_inBase :: (BaseM m x) => Iso m n -> x a -> n a
 derive_inBase iso m = close iso (inBase m)
+
+-- | Derive the implementation of the 'runM' function from 'RunM'.
+derive_runM :: (RunM m a r) => Iso m n -> n a -> r
+derive_runM iso m = runM (open iso m)
diff --git a/src/MonadLib/Monads.hs b/src/MonadLib/Monads.hs
--- a/src/MonadLib/Monads.hs
+++ b/src/MonadLib/Monads.hs
@@ -1,3 +1,7 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
 {-|  This module contains a collection of monads that
    are defined in terms of the monad transformers from
    "MonadLib".   The definitions in this module are
@@ -12,9 +16,7 @@
 ) where
 import MonadLib
 import MonadLib.Derive
-import Control.Monad
 import Control.Monad.Fix
-import Data.Monoid
 
 newtype Reader    i a = R' { unR :: ReaderT    i Id a }
 newtype Writer    i a = W' { unW :: WriterT    i Id a }
@@ -41,36 +43,67 @@
 instance               BaseM (Cont      i) (Cont      i) where inBase = id
 
 instance Monad (Reader i) where
-  return  = derive_return iso_R
-  fail    = derive_fail iso_R
   (>>=)   = derive_bind iso_R
 
+#if !MIN_VERSION_base(4,11,0)
+  fail = error
+#endif
+
 instance (Monoid i) => Monad (Writer i) where
-  return  = derive_return iso_W
-  fail    = derive_fail iso_W
   (>>=)   = derive_bind iso_W
 
+#if !MIN_VERSION_base(4,11,0)
+  fail = error
+#endif
+
 instance Monad (State i) where
-  return  = derive_return iso_S
-  fail    = derive_fail iso_S
   (>>=)   = derive_bind iso_S
 
+#if !MIN_VERSION_base(4,11,0)
+  fail = error
+#endif
+
+
 instance Monad (Exception i) where
-  return  = derive_return iso_X
-  fail    = derive_fail iso_X
   (>>=)   = derive_bind iso_X
 
+#if !MIN_VERSION_base(4,11,0)
+  fail = error
+#endif
+
 instance Monad (Cont i) where
-  return  = derive_return iso_C
-  fail    = derive_fail iso_C
   (>>=)   = derive_bind iso_C
 
+#if !MIN_VERSION_base(4,11,0)
+  fail = error
+#endif
+
 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 Applicative (Reader i) where
+  pure = derive_return iso_R
+  (<*>) = ap
+
+instance (Monoid i) => Applicative (Writer i) where
+  pure = derive_return iso_W
+  (<*>) = ap
+
+instance Applicative (State i) where
+  pure = derive_return iso_S
+  (<*>) = ap
+
+instance Applicative (Exception i) where
+  pure = derive_return iso_X
+  (<*>) = ap
+
+instance Applicative (Cont i) where
+  pure = derive_return iso_C
+  (<*>) = ap
+
 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
@@ -80,7 +113,7 @@
 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
+instance ContM (Cont i) where callWithCC = derive_callWithCC iso_C
 
 runReader     :: i -> Reader i a -> a
 runWriter     :: Writer i a -> (a,i)
