diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,10 @@
-0.1.1.0
-=======
+# 0.1.2.0
+- Added explicit bifunctors dependency.
+- Added Transduce', TransduceM' type synonyms.
+- Added groups', groupsM'.
+
+
+# 0.1.1.0
 
 - Changed signatures of transduce' and transduceM'.
 - generalize' -> generalizeTransducer
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,3 +1,33 @@
-Stateful transducers and streaming-preserving grouping operations for the folds
-in Gabriel Gonzalez's [foldl](http://hackage.haskell.org/package/foldl)
-package.
+## What's in this library?
+
+Stateful transducers and streaming-preserving group operations for the folds in
+Gabriel Gonzalez's [foldl](http://hackage.haskell.org/package/foldl) package.
+
+## When to use this library?
+
+- When you want to wrap a stateful decoder over a **Fold**. An example is
+decoding UTF-8: the decoder must be stateful because a multi-byte character may
+have been split across two blocks of bytes.
+
+- When you want to tweak the stream of data that arrives into a **Fold**, but
+only at certain positions. Stripping whitespace at the beginning of a text
+stream, for example.
+
+- When you want to perform group operations without breaking "streaminess",
+similar to what [pipes-group](http://hackage.haskell.org/package/pipes-group)
+does.
+
+## Why use this library for grouping instead of **pipes-group**?
+
+Grouping fold-side instead of producer-side has the advantage that, since the
+results are still **Fold**s, you can combine them using **Applicative**.
+
+Also, **Fold**s can work with sources other than **Producer**s from pipes.
+
+Grouping fold-side has limitations as well:
+
+- You can't perform bracketing operations like "withFile" that span the folding
+of an entire group. You can do that in pipes-group.
+
+- You have more flexibility in pipes-group to decide how to fold a group based
+on previous results.
diff --git a/foldl-transduce.cabal b/foldl-transduce.cabal
--- a/foldl-transduce.cabal
+++ b/foldl-transduce.cabal
@@ -1,5 +1,5 @@
 Name: foldl-transduce
-Version: 0.1.0.1
+Version: 0.1.2.0
 Cabal-Version: >=1.8.0.2
 Build-Type: Simple
 License: BSD3
@@ -8,7 +8,7 @@
 Author: Daniel Diaz
 Maintainer: diaz_carrete@yahoo.com
 Bug-Reports: https://github.com/danidiaz/foldl-transduce/issues
-Synopsis: Transducers for folds from foldl.
+Synopsis: Transducers for foldl folds.
 Description: Stateful transducers and streaming-preserving grouping operations for the folds in the foldl package.
 Category: Control
 
@@ -28,6 +28,7 @@
         text          >= 0.11.2.0 && < 1.3 ,
         transformers  >= 0.2.0.0  && < 0.5 ,
         containers                   < 0.6 ,
+        bifunctors    == 5.*               ,
         semigroupoids >= 5.0               ,
         foldl         >= 1.1      && < 2   ,
         comonad       == 4.*
diff --git a/src/Control/Foldl/Transduce.hs b/src/Control/Foldl/Transduce.hs
--- a/src/Control/Foldl/Transduce.hs
+++ b/src/Control/Foldl/Transduce.hs
@@ -10,8 +10,10 @@
 module Control.Foldl.Transduce (
         -- * Transducer types
         Transduction 
+    ,   Transduction' 
     ,   Transducer(..)
     ,   TransductionM
+    ,   TransductionM'
     ,   TransducerM(..)
         -- * Applying transducers
     ,   transduce
@@ -34,7 +36,9 @@
     ,   Splitter(..)
         -- * Working with groups
     ,   groups
+    ,   groups'
     ,   groupsM
+    ,   groupsM'
     ,   folds
     ,   foldsM
         -- * Splitters
@@ -54,12 +58,13 @@
 import Control.Comonad
 import Control.Foldl (Fold(..),FoldM(..))
 import qualified Control.Foldl as L
-import Control.Foldl.Transduce.Internal(Pair(..))
+import Control.Foldl.Transduce.Internal (Pair(..),Trio(..))
 
 {- $setup
 
 >>> import qualified Control.Foldl as L
 >>> import Control.Foldl.Transduce
+>>> import Control.Applicative
 
 -}
 
@@ -93,6 +98,12 @@
 type Transduction a b = forall x. Fold b x -> Fold a x
 
 
+{-| A more general from of 'Transduction' that adds new information to the
+    return value of the 'Fold'.
+
+-}
+type Transduction' a b r = forall x. Fold b x -> Fold a (r,x)
+
 {-| Representation of a stateful 'Transduction' with step function, an initial
     accumulator, and a extraction function that returns a summary value of type
     @r@. Both the step function and the extraction function may send output
@@ -112,6 +123,8 @@
 
 type TransductionM m a b = forall x. Monad m => FoldM m b x -> FoldM m a x
 
+type TransductionM' m a b r = forall x. FoldM m b x -> FoldM m a (r,x)
+
 {-| Like 'Transducer', but monadic.
 
 -}
@@ -146,7 +159,7 @@
 >>> L.fold (transduce' (Transducer (\_ i -> ((),[i])) () (\_ -> ('r',[]))) L.list) [1..7]
 ('r',[1,2,3,4,5,6,7])
 -}
-transduce' :: Transducer i o x -> Fold o y -> Fold i (x,y)
+transduce' :: Transducer i o x -> Transduction' i o x
 transduce' (Transducer wstep wstate wdone) (Fold fstep fstate fdone) =
     Fold step (Pair wstate fstate) done 
         where
@@ -163,7 +176,7 @@
 transduceM :: Monad m => TransducerM m i o r -> TransductionM m i o 
 transduceM t = fmap snd . (transduceM' t)
 
-transduceM' :: Monad m => TransducerM m i o x -> FoldM m o y -> FoldM m i (x,y)
+transduceM' :: Monad m => TransducerM m i o x -> TransductionM' m i o x
 transduceM' (TransducerM wstep wstate wdone) (FoldM fstep fstate fdone) =
     FoldM step (liftM2 Pair wstate fstate) done 
         where
@@ -306,6 +319,8 @@
 {-| Applies a 'Transduction' to all groups detected by a 'Splitter', returning
     a 'Transduction' that works over the undivided stream of inputs.		
 
+>>> L.fold (groups (chunksOf 2) (transduce (surround "<" ">")) L.list) "aabbccdd"
+"<aa><bb><cc><dd>"
 -}
 groups :: Splitter i -> Transduction i b -> Transduction i b 
 groups (Splitter sstep sbegin sdone) t f =
@@ -323,6 +338,42 @@
         done (Pair ss (Fold fstep fstate fdone)) = 
             extract (fdone (foldl' fstep fstate (sdone ss)))
 
+{-| Generalized version of 'groups' that obtains a summary value for each
+    group, aggregates them into a summary value for the whole stream, and puts
+    that information in the final result.		
+
+    In practice, this function behaves like a combinaton of 'groups' and
+    'folds' that works in a single pass.
+
+>>> L.fold (groups' (chunksOf 2) L.list (\f -> transduce (surround "<" ">") (liftA2 (,) L.list f)) L.list) "aabbccdd"
+(["<aa>","<bb>","<cc>","<dd>"],"<aa><bb><cc><dd>")
+-}
+groups' :: Splitter i 
+        -> Fold u v -- ^ for aggregating the @u@ values produced for each group
+        -> Transduction' i a u 
+        -> Transduction' i a v -- ^ the resulting 'Fold' will return a summary @v@ of the stream
+groups' (Splitter sstep sbegin sdone) summarizer t f =
+    Fold step (Trio sbegin summarizer (t (duplicated f))) done 
+      where 
+        step (Trio ss summarizer' fs) i = 
+           let 
+               (ss', oldSplit, newSplits) = sstep ss i
+               (summarizer'',fs') = foldl' 
+                   (\(summarizer_,fs_) split_ -> 
+                       let (u, renewed) = reset fs_
+                       in (L.fold (duplicated summarizer_) [u], step' renewed split_))
+                   (summarizer', step' fs oldSplit) 
+                   newSplits
+           in
+           Trio ss' summarizer'' fs'
+        step' = L.fold . duplicated
+        reset (Fold _ fstate fdone) = 
+           let (u,x) = fdone fstate
+           in (u,t (duplicated x))
+        done (Trio ss summarizer' (Fold fstep fstate fdone)) = 
+            let (u,extract -> x) = fdone (foldl' fstep fstate (sdone ss))
+            in (L.fold summarizer' [u],x)
+
 groupsM :: Monad m => Splitter i -> TransductionM m i b -> TransductionM m i b
 groupsM (Splitter sstep sbegin sdone) t f = 
     FoldM step (return (Pair sbegin (t (duplicated f)))) done        
@@ -340,6 +391,35 @@
         done (Pair ss (FoldM fstep fstate fdone)) = do
             finalf <- fdone =<< flip (foldlM fstep) (sdone ss) =<< fstate
             L.foldM finalf [] 
+
+groupsM' :: Monad m => Splitter i -> FoldM m u v -> TransductionM' m i a u -> TransductionM' m i a v 
+groupsM' (Splitter sstep sbegin sdone) summarizer t f =
+    FoldM step (return (Trio sbegin summarizer (t (duplicated f)))) done        
+    where
+        step (Trio ss summarizer' fs) i = do
+            let 
+                (ss', oldSplit, newSplits) = sstep ss i
+            fs' <- step' fs oldSplit
+            (summarizer'',fs'') <- foldlM step'' (summarizer',fs') newSplits
+            return $! Trio ss' summarizer'' fs''
+
+        step' = L.foldM . duplicated
+
+        step'' = \(summarizer_, fs) is -> do
+            (u,fs') <- reset fs 
+            u' <- L.foldM (duplicated summarizer_) [u]
+            fs'' <- step' fs' is
+            return $! (u',fs'') 
+
+        reset (FoldM _ fstate fdone) = do
+           (u,x) <- fdone =<< fstate 
+           return (u, t . duplicated $ x)
+
+        done (Trio ss summarizer' (FoldM fstep fstate fdone)) = do
+            (u,finalf) <- fdone =<< flip (foldlM fstep) (sdone ss) =<< fstate
+            v <- L.foldM summarizer' [u]
+            r <- L.foldM finalf []
+            return (v,r)
 
 {-| Summarizes each group detected by a 'Splitter' using a 'Fold', returning a
     'Transduction' that allows a 'Fold' to accept the original ungrouped input. 
diff --git a/src/Control/Foldl/Transduce/Internal.hs b/src/Control/Foldl/Transduce/Internal.hs
--- a/src/Control/Foldl/Transduce/Internal.hs
+++ b/src/Control/Foldl/Transduce/Internal.hs
@@ -1,7 +1,10 @@
 module Control.Foldl.Transduce.Internal (
         -- * Strict datatypes 
         Pair(..)
+    ,   Trio(..)
     ) where
 
 data Pair a b = Pair !a !b
+
+data Trio a b c = Trio !a !b !c
 
