diff --git a/Data/Conduit/Find.hs b/Data/Conduit/Find.hs
--- a/Data/Conduit/Find.hs
+++ b/Data/Conduit/Find.hs
@@ -1,43 +1,65 @@
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE ViewPatterns #-}
 
 module Data.Conduit.Find
-    ( FileEntry(..)
-    , Predicate
-    , HasFileInfo(..)
-    , consider
-    , entryPath
-    , matchAll
-    , ignoreAll
+    (
+    -- * Introduction
+    -- $intro
+
+    -- ** Basic comparison with GNU find
+    -- $gnufind
+
+    -- ** Performance
+    -- $performance
+
+    -- ** Other notes
+    -- $notes
+
+    -- * Finding functions
+      find
+    , find'
+    , lfind
+    , lfind'
+    , findWithPreFilter
+    , readPaths
+    , stat
+    , lstat
+    , test
+
+    -- * File path predicates
     , ignoreVcs
     , regex
     , glob
-    , stat
-    , lstat
-    , regular
-    , hasMode
-    , executable
     , filename_
     , filenameS_
     , filepath_
     , filepathS_
+    , withPath
+    , entryPath
+
+    -- * File entry predicates (uses stat information)
+    , regular
+    , hasMode
+    , executable
     , depth
     , lastAccessed
     , lastModified
-    , withPath
     , withStatus
-    , prune
-    , test
-    , find
-    , find'
-    , lfind
-    , lfind'
-    , findWithPreFilter
-    , readPaths
+
+    -- * Predicate combinators
     , or_
     , and_
     , not_
+    , prune
+    , matchAll
+    , ignoreAll
+    , consider
+    , (=~)
+
+    -- * Types and type classes
+    , FileEntry(..)
+    , Predicate
+    , HasFileInfo(..)
     ) where
 
 import Conduit
@@ -55,8 +77,126 @@
 import Prelude hiding (FilePath)
 import System.Posix.Files
 import System.Posix.Types
-import Text.Regex.Posix ((=~))
+import qualified Text.Regex.Posix as R ((=~))
 
+{- $intro
+
+**find-conduit** is essentially a souped version of GNU find for Haskell,
+using a DSL to provide both ease of us, and extensive flexbility.
+
+In its simplest form, let's compare some uses of find to find-conduit.  Bear
+in mind that the result of the find function is a conduit, so you're expected
+to either sink it to a list, or operate on the file paths as they are yielded.
+-}
+
+{- $gnufind
+
+A typical find command:
+
+@
+find src -name '*.hs' -type f -print
+@
+
+Would in find-conduit be:
+
+@
+find "src" (glob "*.hs" \<\> regular) $$ mapM_C (liftIO . print)
+@
+
+The 'glob' predicate matches the file basename against the globbing pattern,
+while the 'regular' predicate matches plain files.
+
+A more complicated example:
+
+@
+find . -size +100M -perm 644 -mtime 1
+@
+
+Now in find-conduit:
+
+@
+let megs = 1024 * 1024
+    days = 86400
+now <- liftIO getCurrentTime
+find \".\" ( fileSize (> 100*megs)
+        \<\> hasMode 0o644
+        \<\> lastModified (> addUTCTime now (-(1*days)))
+         )
+@
+
+Appending predicates like this expressing an "and" relationship.  Use '<|>' to
+express "or".  You can also negate any predicate:
+
+@
+find \".\" (not_ (hasMode 0o644))
+@
+
+By default, predicates, whether matching or not, will allow recursion into
+directories.  In order to express that matching predicate should disallow
+recursion, use 'prune':
+
+@
+find \".\" (prune (depth (> 2)))
+@
+
+This is the same as using '-maxdepth 2' in find.
+
+@
+find \".\" (prune (filename_ (== "dist")))
+@
+
+This is the same as:
+
+@
+find . \\( -name dist -prune \\) -o -print
+@
+-}
+
+{- $performance
+
+find-conduit strives to make file-finding a well performing operation.  To
+this end, a composed Predicate will only call stat once per entry being
+considered; and if you prune a directory, it is not traversed at all.
+
+By default, 'find' calls stat for every file before it applies the predicate,
+in order to ensure that only one such call is needed.  Sometimes, however, you
+know just from the FilePath that you don't want to consider a certain file, or
+you want to prune a directory tree.
+
+To support these types of optimized queries, a variant of find is provided
+called 'findWithPreFilter'.  This takes two predicates: one that is applied to
+only the FilePath, before stat (or lstat) is called; and one that is applied
+to the full file information after the stat.
+-}
+
+{- $notes
+
+Predicates form a Category and an Arrow, so you can use Arrow-style
+composition rather than Monoids if you wish.  They also form an Applicative, a
+Monad and a MonadPlus.
+
+In the Monad, the value bound over is whatever the predicate chooses to return
+(most Predicates return the same FilePath they examined, however, making the
+Monad less value).  Here's an example Monad: If the find takes longer than 5
+minutes, abort.  We could have used 'timeout', but this is for illustration.
+
+@
+start <- liftIO getCurrentTime
+find \".\" $ do
+    glob \"*.hs\"
+
+    end <- liftIO getCurrentTime
+    if diffUTCTIme end start > 300
+        then ignoreAll
+        else matchAll
+@
+
+The Predicate Monad is a short-circuiting monad, meaning we stop as soon as it
+can be determined that the user is not interested in a given file.  To access
+the current file, simply bind the result value from any Predicate.  To change
+the file being matched against,for whatever reason, use 'consider'.
+-}
+
 data FileInfo = FileInfo
     { infoPath  :: FilePath
     , infoDepth :: Int
@@ -98,9 +238,23 @@
   where
     vcsDirs = [ ".git", "CVS", "RCS", "SCCS", ".svn", ".hg", "_darcs" ]
 
--- | Find every entry whose filename part matching the given regular expression.
 regex :: (Monad m, HasFileInfo e) => Text -> Predicate m e
-regex pat = filenameS_ (=~ unpack pat)
+regex pat = filename_ (=~ pat)
+
+-- | This is a re-export of 'Text.Regex.Posix.=~', with the types changed for
+--   ease of use with this module.  For example, you can simply say:
+--
+-- @
+--    filename_ (=~ "\\.hs$")
+-- @
+--
+-- Which is the same thing as:
+--
+-- @
+--    regex "\\.hs$"
+-- @
+(=~) :: FilePath -> Text -> Bool
+str =~ pat = encodeString str R.=~ unpack pat
 
 -- | Find every entry whose filename part matching the given filename globbing
 --   expression.  For example: @glob "*.hs"@.
diff --git a/Data/Conduit/Find/Looped.hs b/Data/Conduit/Find/Looped.hs
--- a/Data/Conduit/Find/Looped.hs
+++ b/Data/Conduit/Find/Looped.hs
@@ -103,7 +103,7 @@
             KeepAndRecurse b _ -> runLooped (k b) a
 
 instance Monad m => Category (Looped m) where
-    id = let x = Looped $ \a -> return $ KeepAndRecurse a x in x
+    id = matchAll
     Looped f . Looped g = Looped $ \a -> do
           r <- g a
           case r of
@@ -139,15 +139,15 @@
 
 -- | Within a predicate block, 'consider' a different item than what is
 --   currently being predicated upon.  This makes it possible to write custom
---   logic within the Monad instance for Looped, such as in this contrived
---   example:
+--   logic within the Monad instance for a predicate, such as in this
+--   contrived example:
 --
 -- @
---   flip runLooped "bar.hs" $ do
---       x <- filename_ (== "foo.hs")
---       when (x /= "") $
---           consider "baz.hs" $
---               filename_ (== "baz.hs")    -- passes
+--   flip runLooped \"bar.hs\" $ do
+--       x <- filename_ (== \"foo.hs\")
+--       when (x /= \"\") $
+--           consider \"baz.hs\" $
+--               filename_ (== \"baz.hs\")
 -- @
 consider :: a -> Looped m a b -> Looped m a b
 consider x l = Looped $ const $ runLooped l x
@@ -242,7 +242,7 @@
     f `mappend` g = f <> g
 
 instance Monad m => MonadPlus (Looped m a) where
-    mzero = Looped $ const $ return Ignore
+    mzero = ignoreAll
     Looped f `mplus` Looped g = Looped $ \a -> do
         r <- f a
         case r of
@@ -251,11 +251,18 @@
             RecurseOnly _ -> g a
             KeepAndRecurse b m -> return $ KeepAndRecurse b m
 
+-- | 'matchAll' is id in the 'Predicate' Category.
 matchAll :: Monad m => Predicate m a
 matchAll = Looped $ \entry -> return $ KeepAndRecurse entry matchAll
 
+-- | 'ignore' rejects the current entry, but allows recursion.
+ignore :: Monad m => Looped m a b
+ignore = Looped $ const $ return $ RecurseOnly ignore
+
+-- | 'ignoreAll' rejects every entry, and does not recurse.  This is the same
+--   as 'mzero'.
 ignoreAll :: Monad m => Looped m a b
-ignoreAll = Looped $ const $ return $ RecurseOnly ignoreAll
+ignoreAll = Looped $ const $ return Ignore
 
 -- | 'not_' reverse the meaning of the given predicate, preserving recursion.
 not_ :: MonadIO m => Predicate m a -> Predicate m a
diff --git a/find-conduit.cabal b/find-conduit.cabal
--- a/find-conduit.cabal
+++ b/find-conduit.cabal
@@ -1,5 +1,5 @@
 Name:                find-conduit
-Version:             0.2.2
+Version:             0.2.3
 Synopsis:            A file-finding conduit that allows user control over traversals.
 License-file:        LICENSE
 License:             MIT
@@ -9,7 +9,8 @@
 Cabal-Version:       >=1.10
 Category:            System
 Description:
-  A file-finding conduit that allows user control over traversals.
+  A file-finding conduit that allows user control over traversals.  Please see
+  the module 'Data.Conduit.Find' for more information.
 
 Source-repository head
   type: git
