diff --git a/CC-delcont.cabal b/CC-delcont.cabal
--- a/CC-delcont.cabal
+++ b/CC-delcont.cabal
@@ -1,5 +1,5 @@
 Name:                   CC-delcont
-Version:                0.1
+Version:                0.2
 Description:            An implementation of multi-prompt delimited continuations based
                         on the paper, /A Monadic Framework for Delimited Continuations/,
                         by R. Kent Dybvig, Simon Peyton Jones and Amr Sabry
@@ -15,23 +15,29 @@
 Category:               Control
 License:                OtherLicense
 License-File:           LICENSE
-Copyright:              Copyright (c) 2005--2007, R. Kent Dybvig, Simon Peyton Jones,
+Copyright:              Copyright (c) 2005--2008, R. Kent Dybvig, Simon Peyton Jones,
                         Amr Sabry, Oleg Kiselyov, Chung-chieh Shan
 Author:                 R. Kent Dybvig, Simon Peyton Jones, Amr Sabry, Oleg Kiselyov,
                         Chung-chieh Shan
 Maintainer:             dan.doel@gmail.com
 Homepage:               http://code.haskell.org/~dolio/CC-delcont
+
 Stability:              Experimental
 Tested-With:            GHC
 Build-Depends:          base, mtl
+Build-Type:             Simple
+
 Exposed-Modules:        Control.Monad.CC,
                         Control.Monad.CC.Dynvar,
                         Control.Monad.CC.Seq,
-                        Control.Monad.CC.Prompt
+                        Control.Monad.CC.Prompt,
+                        Control.Monad.CC.Cursor
 Extensions:             MultiParamTypeClasses,
                         UndecidableInstances,
                         FunctionalDependencies,
                         Rank2Types,
-                        GeneralizedNewtypeDeriving
-GHC-Options:            -O2
+                        GeneralizedNewtypeDeriving,
+                        FlexibleInstances,
+                        GADTs
+GHC-Options:            -O2 -Wall
 
diff --git a/Control/Monad/CC.hs b/Control/Monad/CC.hs
--- a/Control/Monad/CC.hs
+++ b/Control/Monad/CC.hs
@@ -1,8 +1,5 @@
-{-# LANGUAGE Rank2Types #-}
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE UndecidableInstances #-}
-{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE Rank2Types, GeneralizedNewtypeDeriving, MultiParamTypeClasses,
+    UndecidableInstances, FunctionalDependencies, FlexibleInstances, GADTs #-}
 
 --------------------------------------------------------------------------
 -- |
@@ -41,10 +38,12 @@
         shift0,
         control0,
         abort
-        -- * examples
-        -- $examples
+        -- * Examples
+        -- $Examples
     ) where
 
+import Control.Applicative
+
 import Control.Monad.Identity
 import Control.Monad.State
 import Control.Monad.Reader
@@ -53,7 +52,9 @@
 import Control.Monad.CC.Seq
 import Control.Monad.CC.Prompt
 
-newtype Frame m ans a b = Frame (a -> CCT ans m b)
+-- newtype Frame m ans a b = Frame (a -> CCT ans m b)
+data Frame m ans a b = FFrame (a -> b)
+                     | MFrame (a -> CCT ans m b)
 
 type Cont ans m a = Seq (Frame m) ans a
 newtype SubCont ans m a b = SC (SubSeq (Frame m) ans a b)
@@ -73,9 +74,16 @@
 --         type 'a'
 newtype CCT ans m a = CCT { unCCT :: Cont ans m a -> P ans m ans }
 
+instance (Monad m) => Functor (CCT ans m) where
+    fmap f (CCT e) = CCT $ \k -> e (PushSeg (FFrame f) k)
+
+instance (Monad m) => Applicative (CCT ans m) where
+    pure  = return
+    (<*>) = ap
+
 instance (Monad m) => Monad (CCT ans m) where
     return v = CCT $ \k -> appk k v
-    (CCT e1) >>= e2 = CCT $ \k -> e1 (PushSeg (Frame e2) k)
+    (CCT e1) >>= e2 = CCT $ \k -> e1 (PushSeg (MFrame e2) k)
 
 instance MonadTrans (CCT ans) where
     lift m = CCT $ \k -> lift m >>= appk k
@@ -93,9 +101,12 @@
 
 -- Applies a continuation to a value. 
 appk :: Monad m => Cont ans m a -> a -> P ans m ans
-appk EmptyS a = return a
-appk (PushP _ k) a = appk k a
-appk (PushSeg (Frame f) k) a = unCCT (f a) k
+appk EmptyS        a = return a
+appk (PushP _ k)   a = appk k a
+appk (PushSeg f k) a = appFrame f a k
+ where
+ appFrame (MFrame g) b l = unCCT (g b) l
+ appFrame (FFrame g) b l = appk l (g b)
 
 -- | Executes a CCT computation, yielding a value in the underlying monad
 runCCT :: (Monad m) => (forall ans. CCT ans m a) -> m a
@@ -103,7 +114,8 @@
 
 -- | The CC monad may be used to execute computations with delimited control.
 newtype CC ans a = CC { unCC :: CCT ans Identity a }
-    deriving (Monad, MonadDelimitedCont (Prompt ans) (SubCont ans Identity))
+    deriving (Functor, Monad, Applicative, 
+                MonadDelimitedCont (Prompt ans) (SubCont ans Identity))
 
 -- | Executes a CC computation, yielding a resulting value.
 runCC  :: (forall ans. CC ans a) -> a
@@ -198,7 +210,7 @@
 abort p e = withSubCont p (\_ -> e)
 
 -------------------------------------------------------------------------------
--- $examples
+-- $Examples
 --
 -- This module provides many different control operators, so hopefully the
 -- examples herein can help in selecting the right ones. The most raw are the
diff --git a/Control/Monad/CC/Cursor.hs b/Control/Monad/CC/Cursor.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/CC/Cursor.hs
@@ -0,0 +1,144 @@
+{-# LANGUAGE GADTs, MultiParamTypeClasses, FunctionalDependencies  #-}
+
+-------------------------------------------------------------------------------
+-- |
+-- Module      : Control.Monad.CC.Cursor
+-- Copyright   : (c) Dan Doel
+-- License     : MIT
+--
+-- Maintainer  : Dan Doel
+-- Stability   : Experimental
+-- Portability : Non-portable (Generalized algebraic data types,
+--                             Functional Dependencies)
+--
+-- Implements various cursor datatypes for iterating over collections
+module Control.Monad.CC.Cursor (
+        Cursor(..),
+        Iterator,
+        generator,
+        iterator,
+        current,
+        next,
+        open,
+        update,
+--        Walkable(..),
+--        Zipper,
+--        zipper,
+--        previousDir,
+--        currentTerm,
+--        move
+    ) where
+
+import Prelude hiding (zip, mapM, mapM_)
+import Control.Monad hiding (mapM, mapM_)
+import Control.Monad.CC
+
+import Data.Maybe
+import Data.Foldable
+import Data.Traversable hiding (traverse)
+
+-- | A generalized type that represents a reified data structure traversal.
+-- The other traversal data types in this module are special cases of this
+-- general type. Cursor is parameterized by four types:
+--
+-- m : The monad in which the Cursor object is usable.
+--
+-- r : The result type, which will be stored in the cursor once the traversal
+--     has been completed.
+--
+-- b : The type that the cursor expects to receive before moving on to the
+--     next element in the traversal.
+--
+-- a : The element type to which the Cursor provides access at each step in
+--     the traversal.
+data Cursor m r b a where
+   Current :: Monad m => a -> (b -> m (Cursor m r b a)) -> Cursor m r b a
+   Done    :: Monad m => r -> Cursor m r b a
+
+-- | A simple iterator, which provides a way to view each of the elements of
+-- a data structure in order.
+type Iterator m a = Cursor m () () a
+
+-- | A function for making a cursor out of a free form generator, similar to
+-- using 'yield' in Ruby or Python. For example:
+--
+-- > generator $ \yield -> do a <- yield 1 ; yield 2 ; b <- yield 3 ; return [a,b]
+generator :: MonadDelimitedCont p s m => ((a -> m b) -> m r) -> m (Cursor m r b a)
+generator f = reset (\p -> Done `liftM` f (yield p))
+ where yield p a = shift p (\k -> return $ Current a (k . return))
+
+-- A general cursor builder; takes the traversal function, a data structure, and
+-- returns a corresponding cursor. Currently not exported, just used internally.
+makeCursor :: (MonadDelimitedCont p s m) =>
+                ((a -> m b) -> t -> m r) -> t -> m (Cursor m r b a)
+makeCursor iter t = generator $ flip iter t
+
+-- | Creates an Iterator that will yield each of the elements of a Foldable in
+-- order.
+iterator :: (Foldable t, MonadDelimitedCont p s m) => t a -> m (Iterator m a)
+iterator = makeCursor mapM_
+
+-- | Advances an Iterator to the next element (has no effect on a finished Iterator).
+next :: Iterator m a -> m (Iterator m a)
+next = update ()
+
+-- | Extracts the current element from a cursor, if applicable.
+current :: Cursor m r b a -> Maybe a
+current (Done _)      = Nothing
+current (Current a _) = Just a
+
+-- | Begins an updating traversal over a Traversable structure. At each step,
+-- the cursor will hold an element of type a, and providing an element of type
+-- b will move on to the next step. When done, a new Traversable object holding
+-- elements of type b will be available.
+open :: (Traversable t, MonadDelimitedCont p s m) => t a -> m (Cursor m (t b) b a)
+open = makeCursor mapM
+
+-- | Provides an item to a Cursor, moving on to the next step in the traversal.
+-- (has no effect on a finished Cursor).
+update :: b -> Cursor m r b a -> m (Cursor m r b a)
+update _ c@(Done _)    = return c
+update b (Current _ k) = k b
+
+-- Removing for now. This isn't remotely done, and I need to reread ccshan's
+-- stuff on zippers and such before I can begin to get it right.
+{-
+class Direction d where
+    nextD :: d -> d
+
+class Direction d => Walkable t d | t -> d where
+    walk :: Monad m => (d -> t -> m (Maybe t, d)) -> t -> m t
+
+data ListDir = LLeft | LRight
+
+instance Direction ListDir where
+    nextD = id
+
+instance Walkable [a] ListDir where
+    walk tr ll = fromMaybe ll `liftM` traverse LRight ll
+     where
+     traverse d l = do (ml, d') <- tr d l
+                       let l' = fromMaybe l ml
+                       maybe ml Just `liftM` select l' d'
+     select _        LLeft  = return Nothing
+     select l@(x:xs) LRight = do l' <- liftM (x:) `liftM` traverse LRight xs
+                                 maybe l' Just `liftM` traverse LLeft (fromMaybe l l')
+     select []       LRight = maybe Nothing Just `liftM` traverse LLeft []
+
+type Zipper m t d = Cursor m t (Maybe t, d) (d,t)
+
+zipper :: (MonadDelimitedCont p s m, Walkable t d) => t -> m (Zipper m t d)
+zipper = makeCursor $ walk . curry
+
+previousDir :: Zipper m t d -> Maybe d
+previousDir (Done _)          = Nothing
+previousDir (Current (d,_) _) = Just d
+
+currentTerm :: Zipper m t d -> t
+currentTerm (Done t)          = t
+currentTerm (Current (_,t) _) = t
+
+move :: d -> Zipper m t d -> m (Zipper m t d)
+move _ z@(Done _) = return z
+move d (Current _ k) = k (Nothing, d)
+-}
diff --git a/Control/Monad/CC/Dynvar.hs b/Control/Monad/CC/Dynvar.hs
--- a/Control/Monad/CC/Dynvar.hs
+++ b/Control/Monad/CC/Dynvar.hs
@@ -1,4 +1,4 @@
-{-# OPTIONS_GHC -fglasgow-exts #-}
+{-# LANGUAGE GADTs #-}
 
 -------------------------------------------------------------------------------
 -- |
diff --git a/Control/Monad/CC/Prompt.hs b/Control/Monad/CC/Prompt.hs
--- a/Control/Monad/CC/Prompt.hs
+++ b/Control/Monad/CC/Prompt.hs
@@ -1,4 +1,4 @@
-{-# OPTIONS_GHC -fglasgow-exts #-}
+{-# LANGUAGE GADTs, GeneralizedNewtypeDeriving #-}
 
 -------------------------------------------------------------------------------
 -- |
diff --git a/Control/Monad/CC/Seq.hs b/Control/Monad/CC/Seq.hs
--- a/Control/Monad/CC/Seq.hs
+++ b/Control/Monad/CC/Seq.hs
@@ -1,4 +1,4 @@
-{-# OPTIONS_GHC -fglasgow-exts #-}
+{-# LANGUAGE GADTs #-}
 
 -------------------------------------------------------------------------------
 -- |
@@ -64,7 +64,7 @@
 -- | Splits a sequence at the given prompt into a sub-sequence, and
 -- the rest of the sequence
 splitSeq :: Prompt ans b -> Seq seg ans a -> (SubSeq seg ans a b, Seq seg ans b)
-splitSeq p EmptyS = error "Prompt was not found on the stack."
+splitSeq _ EmptyS = error "Prompt was not found on the stack."
 splitSeq p (PushP p' sk) =
     case eqPrompt p' p of
          EQU -> (emptySubSeq, sk)
