diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,13 @@
 Changes
 =======
 
+Version 0.3.1
+-------------
+
+* Documentation improvements
+* Add `rfoldMap`
+* Relax Cabal dependency constraint to include Cabal-1.14
+
 Version 0.3
 -----------
 
diff --git a/haskell-names.cabal b/haskell-names.cabal
--- a/haskell-names.cabal
+++ b/haskell-names.cabal
@@ -1,5 +1,5 @@
 Name:                   haskell-names
-Version:                0.3
+Version:                0.3.1
 License:                BSD3
 Author:                 Roman Cheplyaka, Lennart Augustsson
 Maintainer:             Roman Cheplyaka <roma@ro-che.info>
@@ -235,7 +235,7 @@
 source-repository this
   type:     git
   location: git://github.com/haskell-suite/haskell-names.git
-  tag:      v0.3
+  tag:      v0.3.1
 
 Library
   Default-Language: Haskell2010
@@ -243,6 +243,7 @@
       base >= 4 && < 5
     , haskell-src-exts >= 1.14
     , mtl
+    , transformers
     , filepath >= 1.1
     , containers >= 0.2
     , hse-cpp
@@ -255,7 +256,7 @@
     , tagged
     , traverse-with-class
     , type-eq
-    , Cabal >= 1.16 && < 1.20
+    , Cabal >= 1.14 && < 1.20
   Hs-source-dirs:       src
   Ghc-options:          -Wall -fno-warn-name-shadowing
 
diff --git a/src/Language/Haskell/Names/Open.hs b/src/Language/Haskell/Names/Open.hs
--- a/src/Language/Haskell/Names/Open.hs
+++ b/src/Language/Haskell/Names/Open.hs
@@ -3,6 +3,7 @@
   ( Resolvable(..)
   , Alg(..)
   , rmap
+  , rfoldMap
   , Scope
   , NameContext(..)
   , initialScope
diff --git a/src/Language/Haskell/Names/Open/Base.hs b/src/Language/Haskell/Names/Open/Base.hs
--- a/src/Language/Haskell/Names/Open/Base.hs
+++ b/src/Language/Haskell/Names/Open/Base.hs
@@ -1,3 +1,8 @@
+-- | This module provides a more flexible way to process Haskell code —
+-- using an open-recursive traversal.
+--
+-- You can look at "Language.Haskell.Exts.Annotated" source as an example
+-- of how to use this module.
 {-# LANGUAGE RankNTypes, FlexibleInstances, FlexibleContexts, UndecidableInstances, DefaultSignatures, OverlappingInstances, TemplateHaskell, ScopedTypeVariables #-}
 {-# LANGUAGE ImplicitParams, KindSignatures #-}
 module Language.Haskell.Names.Open.Base where
@@ -14,15 +19,20 @@
 import Data.Lens.Template
 import Data.Generics.Traversable
 import Data.Typeable
+import Data.Monoid
+import Data.Functor.Constant
 import GHC.Exts (Constraint)
 
+-- | Describes how we should treat names in the current context
 data NameContext
   = BindingT
   | BindingV
   | ReferenceT
   | ReferenceV
-  | Other -- ^ we don't expect names in this context
+  | Other
 
+-- | Contains information about the node's enclosing scope. Can be
+-- accessed through the lenses: 'gTable', 'lTable', 'nameCtx', 'wcNames'.
 data Scope = Scope
   { _gTable :: Global.Table
   , _lTable :: Local.Table
@@ -32,9 +42,12 @@
 
 makeLens ''Scope
 
+-- | Create an initial scope
 initialScope :: Global.Table -> Scope
 initialScope tbl = Scope tbl Local.empty Other []
 
+-- | The algebra for 'rtraverse'. It's newtype-wrapped because an implicit
+-- parameter cannot be polymorphic.
 newtype Alg w = Alg
   { runAlg :: forall d . Resolvable d => d -> Scope -> w d }
 
@@ -50,7 +63,14 @@
   let ?c = ConstraintProxy :: ConstraintProxy Resolvable
   in gtraverse (\a -> alg a sc) a
 
--- We use Typeable here rather than a class-based approach.
+-- | A type that implements 'Resolvable' provides a way to perform
+-- a shallow scope-aware traversal.
+
+-- There is a generic implementation, 'defaultRtraverse', which is based on
+-- 'GTraversable'. It can be used when there the scope of all the immediate
+-- children is the same as the scope of the current node.
+--
+-- We use 'Typeable' here rather than a class-based approach.
 -- Otherwise, hand-written instances would carry extremely long lists of
 -- constraints, saying that the subterms satisfy the user-supplied class.
 class Typeable a => Resolvable a where
@@ -61,7 +81,7 @@
 instance (Typeable a, GTraversable Resolvable a) => Resolvable a where
   rtraverse = defaultRtraverse
 
--- analogous to gmap, but for Resolvable
+-- | Analogous to 'gmap', but for 'Resolvable'
 rmap
   :: Resolvable a
   => (forall b. Resolvable b => Scope -> b -> b)
@@ -69,6 +89,15 @@
 rmap f sc =
   let ?alg = Alg $ \a sc -> Identity (f sc a)
   in runIdentity . flip rtraverse sc
+
+-- | Analogous to 'gmap', but for 'Resolvable'
+rfoldMap
+  :: (Monoid r, Resolvable a)
+  => (forall b. Resolvable b => Scope -> b -> r)
+  -> Scope -> a -> r
+rfoldMap f sc =
+  let ?alg = Alg $ \a sc -> Constant (f sc a)
+  in getConstant . flip rtraverse sc
 
 intro :: (SrcInfo l, GetBound a l) => a -> Scope -> Scope
 intro node sc =
