diff --git a/examples/accumulate/Main.hs b/examples/accumulate/Main.hs
new file mode 100644
--- /dev/null
+++ b/examples/accumulate/Main.hs
@@ -0,0 +1,16 @@
+module Main (main) where
+
+import Control.Monad (forM_)
+import Data.Monoid (Sum(..))
+import System.Directory.PathWalk (pathWalkAccumulate)
+import System.Environment (getArgs)
+
+main :: IO ()
+main = do
+    rawArgs <- getArgs
+    let args = if rawArgs == [] then ["."] else rawArgs
+    forM_ args $ \arg -> do
+        (Sum total) <- pathWalkAccumulate arg $ \root _dirs files -> do
+            putStrLn $ "files in " ++ root ++ ": " ++ show (length files)
+            return $ Sum (length files)
+        putStrLn $ "Total: " ++ show total
diff --git a/pathwalk.cabal b/pathwalk.cabal
--- a/pathwalk.cabal
+++ b/pathwalk.cabal
@@ -1,5 +1,5 @@
 name:                pathwalk
-version:             0.3.0.0
+version:             0.3.1.0
 synopsis:            Path walking utilities for Haskell programs
 description:         Simple directory tree walking utilities.
 license:             MIT
@@ -57,6 +57,14 @@
   main-is: Main.hs
   build-depends: base, pathwalk
   hs-source-dirs: examples/stoprecursing
+  default-language: Haskell2010
+  ghc-options: -Wall
+
+test-suite accumulate
+  type: exitcode-stdio-1.0
+  main-is: Main.hs
+  build-depends: base, pathwalk
+  hs-source-dirs: examples/accumulate
   default-language: Haskell2010
   ghc-options: -Wall
 
diff --git a/src/System/Directory/PathWalk.hs b/src/System/Directory/PathWalk.hs
--- a/src/System/Directory/PathWalk.hs
+++ b/src/System/Directory/PathWalk.hs
@@ -5,14 +5,17 @@
     , pathWalk
     , WalkStatus(..)
     , pathWalkInterruptible
+    , pathWalkAccumulate
     , pathWalkLazy
     ) where
 
 import Control.Monad (forM, forM_, filterM)
 import Control.Monad.IO.Class (MonadIO, liftIO)
+import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
+import Control.Monad.Trans.Class (lift)
+import Control.Monad.Trans.Writer.Lazy (runWriterT, tell)
 import System.Directory (doesDirectoryExist, doesFileExist, getDirectoryContents)
 import System.FilePath ((</>))
-import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
 import System.IO.Unsafe (unsafeInterleaveIO)
 
 -- | Called with a directory, list of relative subdirectories, and a
@@ -81,6 +84,22 @@
   _ <- pathWalkInternal root callback
   return ()
 
+
+-- | Traverses a directory tree, just like 'pathWalk'.  The difference
+-- is that each callback returns a 'Monoid' value, all of which are
+-- accumulated into the result.  Note that this uses 'WriterT' and
+-- thus frequently appends to the right of the monoid.  Be careful to
+-- avoid accidental quadratic behavior by using a data structure that
+-- supports fast appends.  For example, use Data.Sequence instead of a
+-- list.
+pathWalkAccumulate :: (MonadIO m, Monoid o) => FilePath -> Callback m o -> m o
+pathWalkAccumulate root callback = do
+  ((), result) <- runWriterT $ do
+    pathWalk root $ \dir dirs files -> do
+      r <- lift $ callback dir dirs files
+      tell r
+  return result
+
 -- | The lazy version of 'pathWalk'.  Instead of running a callback
 -- per directory, it returns a lazy list that reads from the
 -- filesystem as the list is evaluated.
@@ -98,3 +117,4 @@
     return $ concat allsubs
     
   return $ (root, dirs, files) : next
+
