diff --git a/monadLib.cabal b/monadLib.cabal
--- a/monadLib.cabal
+++ b/monadLib.cabal
@@ -1,5 +1,5 @@
 Name:           monadLib
-Version:        3.6.2
+Version:        3.7.1
 License:        BSD3
 License-file:   LICENSE
 Author:         Iavor S. Diatchki
diff --git a/src/MonadLib.hs b/src/MonadLib.hs
--- a/src/MonadLib.hs
+++ b/src/MonadLib.hs
@@ -1,5 +1,7 @@
 {-# LANGUAGE CPP, MultiParamTypeClasses, FunctionalDependencies,
              UndecidableInstances, FlexibleInstances #-}
+{-# LANGUAGE Rank2Types #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 {-| This library provides a collection of monad transformers that
     can be combined to produce various monads.
 -}
@@ -20,7 +22,7 @@
   -- * Effect Classes
   -- $Effects
   ReaderM(..), WriterM(..), StateM(..), ExceptionM(..), ContM(..), AbortM(..),
-  Label, labelCC, jump,
+  Label, labelCC, labelCC_, jump, labelC, callCC,
 
   -- * Execution
 
@@ -570,29 +572,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
 --
@@ -718,21 +730,38 @@
 --------------------------------------------------------------------------------
 -- Some convenient functions for working with continuations.
 
--- | An explicit representation for continuations that store a value.
-newtype Label m a    = Lab (a -> m ())
+-- | An explicit representation for monadic continuarions.
+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 -> let label = Lab (\a -> k (a, label))
-                                    in return (x, label))
+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 >> 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
+
+
 
 
 --------------------------------------------------------------------------------
diff --git a/src/MonadLib/Derive.hs b/src/MonadLib/Derive.hs
--- a/src/MonadLib/Derive.hs
+++ b/src/MonadLib/Derive.hs
@@ -1,19 +1,34 @@
+{-# LANGUAGE Rank2Types #-}
+
 {-| 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(..))
 
@@ -26,6 +41,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)
@@ -61,9 +92,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)
diff --git a/src/MonadLib/Monads.hs b/src/MonadLib/Monads.hs
--- a/src/MonadLib/Monads.hs
+++ b/src/MonadLib/Monads.hs
@@ -12,7 +12,6 @@
 ) where
 import MonadLib
 import MonadLib.Derive
-import Control.Monad
 import Control.Monad.Fix
 import Data.Monoid
 
@@ -80,7 +79,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)
