diff --git a/pipes-parse.cabal b/pipes-parse.cabal
--- a/pipes-parse.cabal
+++ b/pipes-parse.cabal
@@ -1,5 +1,5 @@
 Name: pipes-parse
-Version: 2.0.0
+Version: 2.0.1
 Cabal-Version: >=1.8.0.2
 Build-Type: Simple
 License: BSD3
@@ -30,7 +30,7 @@
     HS-Source-Dirs: src
     Build-Depends:
         base         >= 4       && < 5  ,
-        free         >= 3.1     && < 3.5,
+        free         >= 3.1     && < 4.2,
         pipes        >= 4.0     && < 4.1,
         transformers >= 0.2.0.0 && < 0.4
     Exposed-Modules: Pipes.Parse
diff --git a/src/Pipes/Parse.hs b/src/Pipes/Parse.hs
--- a/src/Pipes/Parse.hs
+++ b/src/Pipes/Parse.hs
@@ -8,8 +8,8 @@
 
     * The monadic approach, using parser combinators
 
-    The top half of this module provides the list-like approach.  The key idea
-    is that:
+    The top half of this module provides the list-like approach, which is easier
+    to use, but less powerful.  The key idea is that:
 
 > -- '~' means "is analogous to"
 > Producer a m ()            ~   [a]
@@ -64,10 +64,47 @@
     `Producer` without concatenating elements together, preserving the laziness
     of the underlying 'Producer'.
 
-    The bottom half of this module contains the lower-level monadic parsing
-    primitives.  These are more useful for `pipes` implementers, particularly
-    for building splitters.  I recommend that application developers use the
-    list-like style whenever possible.
+    The bottom half of this module lets you implement your own list-like
+    transformations using monadic parsers.
+
+    For example, if you wanted to repeatedly sum every 3 elements and yield the
+    result, you would write:
+
+> import Control.Monad (unless)
+> import Pipes
+> import qualified Pipes.Prelude as P
+> import Pipes.Parse
+>
+> sum3 :: (Monad m, Num a) => Producer a (StateT (Producer a m ()) m) ()
+> sum3 = do
+>     eof <- lift isEndOfInput
+>     unless eof $ do
+>         n <- lift $ P.sum (input >-> P.take 3)
+>         yield n
+>         sum3
+
+    When you are done building the parser, you convert your parser to a
+    list-like function using `evalStateP`:
+
+> import Pipes.Lift (evalStateP)
+>
+> -- sum3'  ~  (Num a) => [a] -> [a]
+>
+> sum3' :: (Monad m, Num a) => Producer a m () -> Producer a m ()
+> sum3' p = evalStateP p sum3
+
+    ... then apply it to the `Producer` you want to transform:
+
+>>> runEffect $ sum3' (P.readLn >-> P.takeWhile (/= 0)) >-> P.print
+1<Enter>
+4<Enter>
+5<Enter>
+10
+2<Enter>
+0<Enter>
+2
+>>>
+
 -}
 
 {-# LANGUAGE RankNTypes #-}
@@ -80,6 +117,7 @@
 
     -- * Transformations
     takeFree,
+    dropFree,
 
     -- * Joiners
     concat,
@@ -107,12 +145,11 @@
 
 import Control.Applicative ((<$>), (<$))
 import qualified Control.Monad.Trans.Free as F
-import Control.Monad.Trans.Class (lift)
 import Control.Monad.Trans.Free (FreeF(Pure, Free), FreeT(FreeT, runFreeT))
 import qualified Control.Monad.Trans.State.Strict as S
 import Control.Monad.Trans.State.Strict (
     StateT(StateT, runStateT), evalStateT, execStateT )
-import Pipes (Producer, Pipe, await, yield, next, (>->), Producer')
+import Pipes
 import Pipes.Lift (runStateP)
 import qualified Pipes.Prelude as P
 import Prelude hiding (concat, takeWhile)
@@ -177,7 +214,7 @@
             Pure r -> return r
             Free p -> do
                 f' <- p
-                concat f'
+                loop f'
 {-# INLINABLE concat #-}
 
 {-| Join a 'FreeT'-delimited stream of 'Producer's into a single 'Producer' by
@@ -205,7 +242,7 @@
                 go1 f'
 {-# INLINABLE intercalate #-}
 
--- | @(take n)@ only keeps the first @n@ functor layers of a 'FreeT'
+-- | @(takeFree n)@ only keeps the first @n@ functor layers of a 'FreeT'
 takeFree :: (Functor f, Monad m) => Int -> FreeT f m () -> FreeT f m ()
 takeFree = go
   where
@@ -218,6 +255,26 @@
                 Free w  -> return (Free (fmap (go $! n - 1) w))
         else return ()
 {-# INLINABLE takeFree #-}
+
+{-| @(dropFree n)@ peels off the first @n@ layers of a 'FreeT'
+
+    Use carefully: the peeling off is not free.   This runs the first @n@
+    layers, just discarding everything they produce.
+-}
+dropFree
+    :: (Monad m) => Int -> FreeT (Producer a m) m r -> FreeT (Producer a m) m r
+dropFree = go
+  where
+    go n ft
+        | n <= 0 = ft
+        | otherwise = FreeT $ do
+            ff <- runFreeT ft
+            case ff of
+                Pure _ -> return ff
+                Free f -> do
+                    ft' <- runEffect $ for f discard
+                    runFreeT $ go (n-1) ft'
+{-# INLINABLE dropFree #-}
 
 {- $lowlevel
     @pipes-parse@ handles end-of-input and pushback by storing a 'Producer' in
