diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -3,6 +3,9 @@
 A simple way to query constructors, like cases but slightly more
 concise.
 
+Prisms from the lens package can also manage this, but this is a bit
+simpler.
+
 Aimed at sum types with many constructors:
 
 ``` haskell
@@ -23,6 +26,13 @@
 Just (1,'a')
 ```
 
+There is a "map" over a constructor:
+
+``` haskell
+> $(mapCaseOf 'Left) succ (Left 3)
+Left 4
+```
+
 There is a combinator which calls your function with n arguments, or
 passes the whole value to an "else" clause.
 
@@ -30,27 +40,6 @@
 > $(caseOf 'Woo) (\x y -> show x ++ show y) (const "") (Wibble 5)
 ""
 ```
-
-This allows them to be nested:
-
-```haskell
-> $(caseOf 'Woo) (\x y -> show x ++ show y) (const "") (Woo 5 'a')
-"5'a'"
-> $(caseOf 'Woo) (\x y -> show x ++ show y) ($(caseOf 'Wibble) show (const "")) (Woo 5 'a')
-"5'a'"
-```
-
-What's the point of `caseOf`? To more easily dispatch on functions:
-
-```haskell
-handleHuman name age = ...
-handleMachine id = ..
-handleWithDefault def =
-   $(caseOf 'Human) handleHuman .
-   $(caseOf 'Machine) handleMachine def
-```
-
-This applies to any kind of "case" that you'd like to refactor into a function.
 
 ## Use in your project
 
diff --git a/caseof.cabal b/caseof.cabal
--- a/caseof.cabal
+++ b/caseof.cabal
@@ -1,5 +1,5 @@
 name:                caseof
-version:             0.0.0
+version:             0.0.1
 synopsis:            Combinators for casing on constructors
 description:         Template-Haskell-based combinators that let you select on constructors.
 homepage:            https://github.com/chrisdone/caseof#readme
diff --git a/src/CaseOf.hs b/src/CaseOf.hs
--- a/src/CaseOf.hs
+++ b/src/CaseOf.hs
@@ -2,8 +2,15 @@
 {-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE TemplateHaskell #-}
 
-module CaseOf where
+-- | Template-Haskell-based combinators that let you select on constructors.
 
+module CaseOf
+  (isCaseOf
+  ,maybeCaseOf
+  ,mapCaseOf
+  ,caseOf)
+  where
+
 import Language.Haskell.TH
 import Language.Haskell.TH.Syntax
 
@@ -34,6 +41,37 @@
            ])
     _ -> fail ("Invalid data constructor " ++ pprint input)
   where
+    varI i = VarE (mkName ("v" ++ show i))
+    patI i = VarP (mkName ("v" ++ show i))
+    arity (ForallT _ _ t) = arity t
+    arity (AppT (AppT ArrowT _) y) = 1 + arity y
+    arity _ = 0
+
+-- | Apply a function to the slots of a constructor, if it matches,
+-- otherwise identity.
+mapCaseOf :: Name -> Q Exp
+mapCaseOf input = do
+  name <- nameAsValue input
+  info <- reify name
+  case info of
+    DataConI _ ty _ ->
+      pure
+        (LamE
+           [VarP f]
+           (LamCaseE
+              [ Match
+                  (ConP name (map patI [1 .. arity ty]))
+                  (NormalB
+                     (AppE
+                        (ConE name)
+                        (foldl AppE (VarE f) (map varI [1 .. arity ty]))))
+                  []
+              , Match (VarP this) (NormalB (VarE this)) []
+              ]))
+    _ -> fail ("Invalid data constructor " ++ pprint input)
+  where
+    f = mkName "f"
+    this = mkName "this"
     varI i = VarE (mkName ("v" ++ show i))
     patI i = VarP (mkName ("v" ++ show i))
     arity (ForallT _ _ t) = arity t
