diff --git a/example/Main.hs b/example/Main.hs
new file mode 100644
--- /dev/null
+++ b/example/Main.hs
@@ -0,0 +1,16 @@
+module Main (main) where
+
+import Control.Monad (forM_)
+import Data.List (intercalate)
+import System.Directory.PathWalk (pathWalk)
+import System.Environment (getArgs)
+
+main :: IO ()
+main = do
+  rawArgs <- getArgs
+  let args = if rawArgs == [] then ["."] else rawArgs
+  forM_ args $ \arg -> do
+    pathWalk arg $ \root dirs files -> do
+      putStrLn root
+      putStrLn $ "  dirs: " ++ show dirs
+      putStrLn $ "  files: " ++ show files
diff --git a/pathwalk.cabal b/pathwalk.cabal
--- a/pathwalk.cabal
+++ b/pathwalk.cabal
@@ -1,21 +1,49 @@
 name:                pathwalk
-version:             0.1.1.1
+version:             0.2.0.0
 synopsis:            Path walking utilities for Haskell programs
 description:         Simple directory tree walking utilities.
 license:             MIT
 license-file:        LICENSE
 author:              Christine Dodrill
 maintainer:          xena@yolo-swag.com
+homepage:            https://github.com/Xe/pathwalk
 category:            System
 build-type:          Simple
 cabal-version:       >=1.10
 
+description:
+
+    "System.Directory.PathWalk" is an implementation of Python's excellent
+    os.walk function.  Given a root directory, it recursively scans all
+    subdirectories, calling a callback with directories and files it finds.
+    Importantly, it calls the callback as soon as it finishes scanning each
+    directory to allow the caller to begin processing results immediately.
+    .
+    Maximum memory usage is O(N+M) where N is the depth of the tree and M
+    is the maximum number of entries in a particular directory.
+    .
+    > import System.Directory.PathWalk
+    >
+    > pathWalk "some/directory" $ \root dirs files -> do
+    >   forM_ files $ \file ->
+    >     when (".hs" `isSuffixOf` file) $ do
+    >       putStrLn $ joinPath [root, file]
+
 source-repository head
     type: git
     location: https://github.com/Xe/pathwalk
 
 library
   exposed-modules:     System.Directory.PathWalk
-  build-depends:       base >=4.6 && <4.7, directory >=1.2 && <1.3, filepath >=1.3 && <1.4
-  hs-source-dirs:      src
-  default-language:    Haskell2010
+  build-depends:
+      base >=3 && <5
+    , directory >=1.2
+    , filepath >=1.3
+  hs-source-dirs: src
+  default-language: Haskell2010
+
+executable example
+  main-is: Main.hs
+  build-depends: base, pathwalk
+  hs-source-dirs: example
+  default-language: Haskell2010
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
@@ -1,33 +1,32 @@
-module Within.PathWalk where
+module System.Directory.PathWalk
+    ( pathWalk
+    ) where
 
-import Control.Monad (forM_)
+import Control.Monad (forM_, filterM)
 import Data.IORef (newIORef, readIORef, writeIORef)
-import System.Directory (doesDirectoryExist, getDirectoryContents)
+import System.Directory (doesDirectoryExist, doesFileExist, getDirectoryContents)
 import System.FilePath ((</>))
 
+-- | 'pathWalk' recursively enumerates the given root directory,
+-- calling callback once per directory with the traversed directory name, a list of subdirectories, and a list of files.
+--
+-- The subdirectories and file names are always relative to the root given.
+--
+-- @
+-- pathWalk "src" $ \\dir subdirs files -> do
+--   forM_ files $ \\file -> do
+--     when ("Test.hs" \`isSuffixOf\` file) $ do
+--       registerTestFile $ dir \</\> file
+-- @
 pathWalk :: FilePath -> (FilePath -> [FilePath] -> [FilePath] -> IO ()) -> IO ()
 pathWalk root callback = do
-    dirs  <- newIORef ([] :: [FilePath])
-    files <- newIORef ([] :: [FilePath])
     names <- getDirectoryContents root
     let properNames = filter (`notElem` [".", ".."]) names
 
-    forM_ properNames $ \name -> do
-        isDir <- doesDirectoryExist $ root </> name
-
-        case isDir of
-            True -> do
-                val <- readIORef dirs
-                writeIORef dirs $ val ++ [name]
-            False -> do
-                val <- readIORef files
-                writeIORef files $ val ++ [name]
-
-    cbDirs  <- readIORef dirs
-    cbFiles <- readIORef files
+    dirs <- filterM (\n -> doesDirectoryExist $ root </> n) names
+    files <- filterM (\n -> doesFileExist $ root </> n) names
 
-    callback root cbDirs cbFiles
+    callback root dirs files
 
-    forM_ cbDirs $ \dir -> do
-        let newPath = root </> dir
-        pathWalk newPath callback
+    forM_ dirs $ \dir -> do
+        pathWalk (root </> dir) callback
