diff --git a/quiver-cell.cabal b/quiver-cell.cabal
--- a/quiver-cell.cabal
+++ b/quiver-cell.cabal
@@ -1,5 +1,5 @@
 name:           quiver-cell
-version:        0.0.0.1
+version:        0.0.0.2
 synopsis:       Quiver combinators for cellular data processing
 homepage:       https://github.com/zadarnowski/quiver-cell
 category:       Control
@@ -28,7 +28,7 @@
 source-repository this
   type:         git
   location:     https://github.com/zadarnowski/quiver-cell.git
-  tag:          0.0.0.1
+  tag:          0.0.0.2
 
 library
   hs-source-dirs:   src
@@ -41,4 +41,4 @@
   build-depends:
     base                    >= 4.8 && < 5,
     data-cell               >= 1.0.0.2,
-    quiver                  >= 0.0.0.6
+    quiver                  >= 0.0.0.11
diff --git a/src/Control/Quiver/Cell.lhs b/src/Control/Quiver/Cell.lhs
--- a/src/Control/Quiver/Cell.lhs
+++ b/src/Control/Quiver/Cell.lhs
@@ -13,35 +13,32 @@
 > ) where
 
 > import Data.Cell
-> import Control.Quiver
+> import Control.Quiver.SP
 
 > -- | A simple Quiver processor that converts a stream of cells into a stream of rows,
 > --   with each row represented by a non-empty list of cell values.
 
-> toRows :: (Monoid a) => SP (Cell a) [a] f ()
+> toRows :: Monoid a => SP (Cell a) [a] f e
 > toRows = loop0
 >  where
 >   loop0 = loop1 [] []
->   loop1 row cell = consume () (loop2 row cell) (emit_ (assemble row cell))
+>   loop1 row cell = consume () (loop2 row cell) (spemit (assemble row cell))
 >   loop2 row cell (Cell part d) =
 >     case d of
 >       EOP -> loop1 row cell'
 >       EOC -> loop1 (mconcat (reverse cell') : row) []
->       _   -> produce (assemble row cell') (const $ loop0) (deliver ())
+>       _   -> assemble row cell' >:> loop0
 >    where
 >     cell' = part:cell
 >   assemble row cell = reverse (mconcat (reverse cell) : row)
 
-> -- | A simple Quiver processor that converts a stream of rows to a stream of cells,
+> -- | A simple Quiver processor that converts a stream of rows to a stream of cells.
 > --   In this version, the final cell in the table is not marked with @EOT@ to avoid
-> --   the need for row lookahead, delivering the list of any cells that could not
-> --   be produced from the final consumed row.
-> --
-> --   Empty input rows are ignored.
+> --   the need for row lookahead.  Empty input rows are ignored.
 
-> fromRows :: SP [a] (Cell a) f [a]
+> fromRows :: SP [a] (Cell a) f e
 > fromRows = loop0
 >  where
->   loop0 = consume () loop1 (deliver [])
->   loop1 (x:xs) = produce (Cell x (if null xs then EOR else EOC)) (const $ loop1 xs) (deliver xs)
+>   loop0 = consume () loop1 (deliver SPComplete)
+>   loop1 (x:xs) = Cell x (if null xs then EOR else EOC) >:> loop1 xs
 >   loop1 [] = loop0
