diff --git a/CHANGES.md b/CHANGES.md
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,6 +1,11 @@
 Changes
 =======
 
+Version 0.2
+-----------
+
+Implement a zipper
+
 Version 0.1.1.1
 ---------------
 
diff --git a/Data/Generics/Traversable/Instances.hs b/Data/Generics/Traversable/Instances.hs
--- a/Data/Generics/Traversable/Instances.hs
+++ b/Data/Generics/Traversable/Instances.hs
@@ -18,10 +18,13 @@
 instance GTraversable c Char
 instance GTraversable c Ordering
 
-deriveGTraversable ''Maybe
-deriveGTraversable ''Either
-deriveGTraversable ''(,)
-deriveGTraversable ''(,,)
+--deriveGTraversable ''Maybe
+instance c_0 a_1 => Data.Generics.Traversable.Core.GTraversable c_0
+                                                                (Maybe a_1)
+    where gtraverse = \f_2 x_3 -> case x_3 of
+                                                                     Nothing -> Control.Applicative.pure Nothing
+                                                                     Just arg_4 -> (Control.Applicative.<*>) (Control.Applicative.pure Just) (f_2 arg_4)
+
 
 -- Uniform instance for lists
 instance c a => GTraversable c [a] where
diff --git a/Data/Generics/Traversable/TH.hs b/Data/Generics/Traversable/TH.hs
--- a/Data/Generics/Traversable/TH.hs
+++ b/Data/Generics/Traversable/TH.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE CPP, TemplateHaskell #-}
 -- | For the generated instances you'll typically need the following
 -- extensions:
 --
@@ -90,7 +90,12 @@
 
     types = nub [ t | (_,_,ts) <- constructors, t <- ts ]
 
+#if MIN_VERSION_template_haskell(2,10,0)
+-- see https://ghc.haskell.org/trac/ghc/ticket/9270
+    userContext = [ varT ctx `appT` pure t | t <- types ]
+#else
     userContext = [ classP ctx [pure t] | t <- types ]
+#endif
 
   sequence [inst]
 
diff --git a/Data/Generics/Traversable/Zipper.hs b/Data/Generics/Traversable/Zipper.hs
new file mode 100644
--- /dev/null
+++ b/Data/Generics/Traversable/Zipper.hs
@@ -0,0 +1,280 @@
+-- | Based on «Scrap Your Zippers: A Generic Zipper for Heterogeneous Types.
+-- Michael D. Adams.  WGP '10: Proceedings of the 2010 ACM SIGPLAN
+-- workshop on Generic programming, 2010»
+-- (<http://www.cs.indiana.edu/~adamsmd/papers/scrap_your_zippers/>).
+--
+-- Unlike the original @syz@ package, this implementation (based on
+-- 'GTraversable') gives more flexibility as to where a zipper may point
+-- to and what is considered as siblings.
+--
+-- Specifically, a zipper may point to any element which `gtraverse`
+-- applies its function to.
+--
+-- == Example
+-- === syz
+-- Consider the classical example: lists. With syz, a list is interpreted as a right-balanced
+-- tree.
+--
+-- >>> let z = fromJust . down' $ toZipper ['a'..'d']
+-- >>> getHole z :: Maybe Char
+-- Just 'a'
+--
+-- The zipper @z@ points to the first element of the list. Now let's
+-- move to the right:
+--
+-- >>> let z' = fromJust . right $ z
+-- >>> getHole z' :: Maybe Char
+-- Nothing
+-- >>> getHole z' :: Maybe [Char]
+-- Just "bcd"
+--
+-- Instead of pointing to the second element of the list, as one might
+-- expect, the zipper @z\'@ points to the tail of the list. In order to
+-- actually move to the second element, we need another 'down'':
+--
+-- >>> let z'' = fromJust . down' $ z'
+-- >>> getHole z'' :: Maybe Char
+-- Just 'b'
+--
+-- === traverse-with-class
+-- 'GTraversable'-based zippers behave more intuitively in this regard,
+-- thanks to the uniform instance for lists.
+--
+-- >>> let z = fromJust . down' $ toZipper ['a'..'d'] :: Zipper Typeable [Char]
+-- >>> getHole z :: Maybe Char
+-- Just 'a'
+--
+-- So far it's more or less the same as with syz. We needed to add a type
+-- annotation for the zipper itself to clarify the context which should
+-- be available at each hole ('Typeable' in this case). Now let's see
+-- what's to the right of us:
+--
+-- >>> let z' = fromJust . right $ z
+-- >>> getHole z' :: Maybe Char
+-- Just 'b'
+--
+-- That is, we jumped right to the second element of the list. Likewise,
+--
+-- >>> let z'' = rightmost z
+-- >>> getHole z'' :: Maybe Char
+-- Just 'd'
+--
+-- So, unlike in @syz@, all of the list elements are siblings.
+{-# LANGUAGE Rank2Types, GADTs, KindSignatures, ImplicitParams,
+             ScopedTypeVariables, ConstraintKinds,
+             MultiParamTypeClasses, UndecidableInstances #-}
+
+module Data.Generics.Traversable.Zipper (
+  -- * Core types
+  Zipper(),
+
+  -- * Core interface
+  -- ** Injection and projection
+  toZipper, fromZipper,
+  -- ** Basic movement
+  left, right, down, down', up, leftmost, rightmost,
+
+  -- ** Basic hole manipulation
+  query,
+  trans,
+  transM,
+
+  -- * Convenience hole manipulation interface
+  -- | It does not appear easy to make these functions polymorphic over the constraint @c@.
+  --
+  -- If you want these functions for your own constraint (which entails
+  -- 'Typeable'), you need to copy their definitions and change 'Typeable'
+  -- to your constraint in the 'Zipper' \'s argument.
+  getHole,
+  setHole,
+  setHole'
+  ) where
+
+import Control.Monad ((<=<), MonadPlus, mzero, mplus, liftM)
+import Data.Maybe (fromJust)
+import Data.Generics.Traversable
+import Data.Typeable
+import Data.Proxy
+import GHC.Exts (Constraint)
+import Control.Applicative
+
+-- Core types
+
+-- | A generic zipper with a root object of type @root@.
+data Zipper (c :: * -> Constraint) root =
+  forall hole. (Rec c hole) =>
+    Zipper hole (Context c hole root)
+
+---- Internal types and functions
+data Context c hole root where
+    CtxtNull :: Context c a a
+    CtxtCons ::
+      forall hole root rights parent c. (Rec c parent) =>
+        Left c (hole -> rights)
+        -> Right c rights parent
+        -> Context c parent root
+        -> Context c hole root
+
+combine :: Left c (hole -> rights)
+         -> hole
+         -> Right c rights parent
+         -> parent
+combine lefts hole rights =
+  fromRight ((fromLeft lefts) hole) rights
+
+-- Left is essentially Ørjan Johansen’s free applicative functor.
+-- (see http://ro-che.info/articles/2013-03-31-flavours-of-free-applicative-functors.html)
+--
+-- This allows us to convert any GTraversable value to a zipper.
+data Left c expects
+  = LeftUnit expects
+  | forall b. (Rec c b) => LeftCons (Left c (b -> expects)) b
+
+instance Functor (Left c) where
+  fmap f (LeftUnit x) = LeftUnit $ f x
+  fmap f (LeftCons lft x) = LeftCons (fmap (f .) lft) x
+
+instance Applicative (Left c) where
+  pure = LeftUnit
+  tx <*> LeftUnit e = fmap ($ e) tx
+  tx <*> LeftCons ty az = LeftCons ((.) <$> tx <*> ty) az
+
+unit :: Rec c b => b -> Left c b
+unit = LeftCons (LeftUnit id)
+
+toLeft :: forall a c . (Rec c a) => a -> Left c a
+toLeft =
+  let ?c = Proxy :: Proxy (Rec c) in
+    gtraverse unit
+
+fromLeft :: Left c r -> r
+fromLeft (LeftUnit a)   = a
+fromLeft (LeftCons f b) = fromLeft f b
+
+data Right c provides parent where
+  RightNull :: Right c parent parent
+  RightCons ::
+    (Rec c b) => b -> Right c a t -> Right c (b -> a) t
+
+fromRight :: r -> Right c r parent -> parent
+fromRight f (RightNull)     = f
+fromRight f (RightCons b r) = fromRight (f b) r
+
+-- Core interface
+
+---- Injection and projection
+
+-- | Move up a zipper to the root and return the root object.
+fromZipper :: Zipper c a -> a
+fromZipper (Zipper hole CtxtNull) = hole
+fromZipper (Zipper hole (CtxtCons l r ctxt)) =
+  fromZipper (Zipper (combine l hole r) ctxt)
+
+-- | Create a zipper.  The focus starts at the root of the object.
+toZipper :: Rec c a => a -> Zipper c a
+toZipper x = Zipper x CtxtNull
+
+---- Basic movement
+
+-- | Move left.  Returns 'Nothing' iff already at leftmost sibling.
+left  :: Zipper c a -> Maybe (Zipper c a)
+left (Zipper _ CtxtNull) = Nothing
+left (Zipper _ (CtxtCons (LeftUnit _) _ _)) = Nothing
+left (Zipper h (CtxtCons (LeftCons l h') r c)) =
+  Just (Zipper h' (CtxtCons l (RightCons h r) c))
+
+-- | Move right.  Returns 'Nothing' iff already at rightmost sibling.
+right :: Zipper c a -> Maybe (Zipper c a)
+right (Zipper _ CtxtNull) = Nothing
+right (Zipper _ (CtxtCons _ RightNull _)) = Nothing
+right (Zipper h (CtxtCons l (RightCons h' r) c)) =
+  Just (Zipper h' (CtxtCons (LeftCons l h) r c))
+
+-- | Move down.  Moves to rightmost immediate child.  Returns 'Nothing' iff at a leaf and thus no children exist.
+down  :: forall a c . Zipper c a -> Maybe (Zipper c a)
+down (Zipper (hole :: holeT) ctxt) =
+  case toLeft hole :: Left c holeT of
+    LeftUnit _ -> Nothing
+    LeftCons l hole' ->
+      Just (Zipper hole' (CtxtCons l RightNull ctxt))
+
+-- | Move down. Move to the leftmost immediate child.  Returns 'Nothing' iff at a leaf and thus no children exist.
+down' :: Zipper c a -> Maybe (Zipper c a)
+down' z = liftM leftmost (down z)
+
+-- | Move up.  Returns 'Nothing' iff already at root and thus no parent exists.
+up    :: Zipper c a -> Maybe (Zipper c a)
+up (Zipper _ CtxtNull) = Nothing
+up (Zipper hole (CtxtCons l r ctxt)) =
+  Just (Zipper (combine l hole r) ctxt)
+
+---- Basic hole manipulation
+
+-- | Apply a generic query to the hole.
+query
+  :: (forall a . Rec c a => a -> b)
+  -> Zipper c a -> b
+query f (Zipper hole _ctxt) = f hole
+
+-- | Apply a generic transformation to the hole.
+trans
+  :: (forall a . Rec c a => a -> a)
+  -> Zipper c a -> Zipper c a
+trans f (Zipper hole ctxt) = Zipper (f hole) ctxt
+
+-- | Apply a generic monadic transformation to the hole
+transM
+  :: Monad m
+  => (forall a . Rec c a => a -> m a)
+  -> Zipper c a -> m (Zipper c a)
+transM f (Zipper hole ctxt) = do
+  hole' <- f hole
+  return (Zipper hole' ctxt)
+
+-- Convenience hole manipulation interface
+
+-- | Get the value in the hole.  Returns 'Nothing' iff @a@ is not the type of the value in the hole.
+getHole :: (Typeable b) => Zipper Typeable a -> Maybe b
+getHole = query cast
+
+-- | Set the value in the hole.  Does nothing iff @a@ is not the type of the value in the hole.
+setHole :: (Typeable a) => a -> Zipper Typeable b -> Zipper Typeable b
+setHole h z = trans (maybe id const $ cast h) z
+
+-- | Set the value in the hole.  Returns 'Nothing' iff @a@ is not the type of the value in the hole.
+setHole' :: (Typeable a) => a -> Zipper Typeable b -> Maybe (Zipper Typeable b)
+setHole' h z = transM (const (cast h)) z
+-- Generic zipper traversals
+---- Traversal helpers
+
+-- | A movement operation such as 'left', 'right', 'up', or 'down'.
+type Move c a = Zipper c a -> Maybe (Zipper c a)
+
+-- | Apply a generic query using the specified movement operation.
+moveQ :: Move c a -- ^ Move operation
+      -> b -- ^ Default if can't move
+      -> (Zipper c a -> b) -- ^ Query if can move
+      -> Zipper c a -- ^ Zipper
+      -> b
+moveQ move b f z = case move z of
+                     Nothing -> b
+                     Just z' -> f z'
+
+------ Query
+-- | Apply a generic query to the left sibling if one exists.
+leftQ :: b -- ^ Value to return of no left sibling exists.
+      -> (Zipper c a -> b) -> Zipper c a -> b
+leftQ b f z = moveQ left b f z
+
+-- | Apply a generic query to the right sibling if one exists.
+rightQ :: b -- ^ Value to return if no right sibling exists.
+       -> (Zipper c a -> b) -> Zipper c a -> b
+rightQ b f z = moveQ right b f z
+
+-- | Move to the leftmost sibling.
+leftmost :: Zipper c a -> Zipper c a
+leftmost z = leftQ z leftmost z
+
+-- | Move to the rightmost sibling.
+rightmost :: Zipper c a -> Zipper c a
+rightmost z = rightQ z rightmost z
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -4,3 +4,13 @@
 functions. It is similar to syb-with-class, but has many improvements.
 
 [Hackage](http://hackage.haskell.org/package/traverse-with-class)
+
+Maintainers
+-----------
+
+[Roman Cheplyaka](https://github.com/feuerbach) is the primary maintainer.
+
+[Sjoerd Visscher](https://github.com/sjoerdvisscher) and
+[Adam Bergmark](https://github.com/bergmark)
+are the backup maintainers. Please get in touch with them if the primary
+maintainer cannot be reached.
diff --git a/traverse-with-class.cabal b/traverse-with-class.cabal
--- a/traverse-with-class.cabal
+++ b/traverse-with-class.cabal
@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                traverse-with-class
-version:             0.1.1.1
+version:             0.2
 synopsis:            Generic applicative traversals
 description:         This is a generic programming library in the spirit of
                      \"Scrap your boilerplate with class\", but with several
@@ -26,6 +26,7 @@
 library
   exposed-modules:     Data.Generics.Traversable
                        Data.Generics.Traversable.TH
+                       Data.Generics.Traversable.Zipper
   other-modules:
                        Data.Generics.Traversable.Core
                        Data.Generics.Traversable.Instances
