packages feed

foldl-transduce 0.1.2.3 → 0.2.0.0

raw patch · 5 files changed

+166/−130 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Control.Foldl.Transduce: Splitter :: (x -> i -> (x, [i], [[i]])) -> x -> (x -> [i]) -> Splitter i
- Control.Foldl.Transduce: chokepoint :: Fold i b -> Transducer i b ()
- Control.Foldl.Transduce: chokepointM :: Applicative m => FoldM m i b -> TransducerM m i b ()
- Control.Foldl.Transduce: data Splitter i
- Control.Foldl.Transduce: generalizeTransducer :: Monad m => Transducer i o r -> TransducerM m i o r
- Control.Foldl.Transduce: simplifyTransducer :: TransducerM Identity i o r -> Transducer i o r
+ Control.Foldl.Transduce: _generalize :: Monad m => Transducer i o r -> TransducerM m i o r
+ Control.Foldl.Transduce: _simplify :: TransducerM Identity i o r -> Transducer i o r
+ Control.Foldl.Transduce: folds' :: Transducer i i' s -> Fold i' b -> Transduction' i b s
+ Control.Foldl.Transduce: foldsM' :: (Applicative m, Monad m) => TransducerM m i i' s -> FoldM m i' b -> TransductionM' m i b s
+ Control.Foldl.Transduce.Internal: fstOf3 :: (a, b, c) -> a
- Control.Foldl.Transduce: Transducer :: (x -> i -> (x, [o])) -> x -> (x -> (r, [o])) -> Transducer i o r
+ Control.Foldl.Transduce: Transducer :: (x -> i -> (x, [o], [[o]])) -> x -> (x -> (r, [o])) -> Transducer i o r
- Control.Foldl.Transduce: TransducerM :: (x -> i -> m (x, [o])) -> (m x) -> (x -> m (r, [o])) -> TransducerM m i o r
+ Control.Foldl.Transduce: TransducerM :: (x -> i -> m (x, [o], [[o]])) -> (m x) -> (x -> m (r, [o])) -> TransducerM m i o r
- Control.Foldl.Transduce: chunksOf :: Int -> Splitter a
+ Control.Foldl.Transduce: chunksOf :: Int -> Transducer a a ()
- Control.Foldl.Transduce: folds :: Splitter i -> Fold i b -> Transduction i b
+ Control.Foldl.Transduce: folds :: Transducer i i' r -> Fold i' b -> Transduction i b
- Control.Foldl.Transduce: foldsM :: (Applicative m, Monad m) => Splitter i -> FoldM m i b -> TransductionM m i b
+ Control.Foldl.Transduce: foldsM :: (Applicative m, Monad m) => TransducerM m i i' r -> FoldM m i' b -> TransductionM m i b
- Control.Foldl.Transduce: groups :: Splitter i -> Transduction i b -> Transduction i b
+ Control.Foldl.Transduce: groups :: Transducer i i' r -> Transduction i' b -> Transduction i b
- Control.Foldl.Transduce: groups' :: Splitter i -> Fold u v -> Transduction' i a u -> Transduction' i a v
+ Control.Foldl.Transduce: groups' :: Transducer i i' s -> Fold u v -> Transduction' i' a u -> Transduction' i a (s, v)
- Control.Foldl.Transduce: groupsM :: Monad m => Splitter i -> TransductionM m i b -> TransductionM m i b
+ Control.Foldl.Transduce: groupsM :: Monad m => TransducerM m i i' s -> TransductionM m i' b -> TransductionM m i b
- Control.Foldl.Transduce: groupsM' :: Monad m => Splitter i -> FoldM m u v -> TransductionM' m i a u -> TransductionM' m i a v
+ Control.Foldl.Transduce: groupsM' :: Monad m => TransducerM m i i' s -> FoldM m u v -> TransductionM' m i' a u -> TransductionM' m i a (s, v)
- Control.Foldl.Transduce.Text: lines :: Splitter Text
+ Control.Foldl.Transduce.Text: lines :: Transducer Text Text ()

Files

CHANGELOG view
@@ -1,3 +1,10 @@+# 0.2.0.0+- Removed the Spliiter type. Now it's transducers for everything!+- generalizeTransducer -> _generalize+- simplifyTransducer -> _simplify+- removed chokepoint and chokepointM++ # 0.1.2.0 - Added explicit bifunctors dependency. - Added Transduce', TransduceM' type synonyms.
foldl-transduce.cabal view
@@ -1,5 +1,5 @@ Name: foldl-transduce-Version: 0.1.2.3+Version: 0.2.0.0 Cabal-Version: >=1.8.0.2 Build-Type: Simple License: BSD3
src/Control/Foldl/Transduce.hs view
@@ -20,29 +20,27 @@     ,   transduce'     ,   transduceM     ,   transduceM'-        -- * Transducers-    ,   surround-    ,   surroundIO-        -- * Transducer utilities-    ,   generalizeTransducer-    ,   simplifyTransducer-    ,   foldify-    ,   foldifyM-    ,   chokepoint -    ,   chokepointM-    ,   hoistTransducer-    ,   hoistFold-        -- * Splitter types-    ,   Splitter(..)         -- * Working with groups     ,   groups     ,   groups'     ,   groupsM     ,   groupsM'     ,   folds+    ,   folds'     ,   foldsM+    ,   foldsM'+        -- * Transducers+    ,   surround+    ,   surroundIO         -- * Splitters     ,   chunksOf+        -- * Transducer utilities+    ,   _generalize+    ,   _simplify+    ,   foldify+    ,   foldifyM+    ,   hoistTransducer+    ,   hoistFold         -- * Re-exports         -- $reexports     ,   module Data.Functor.Extend@@ -50,6 +48,7 @@     ) where  import Data.Bifunctor+import Data.Monoid import Data.Functor.Identity import Data.Functor.Extend import Data.Foldable (Foldable,foldlM,foldl',toList)@@ -59,7 +58,7 @@ import Control.Comonad import Control.Foldl (Fold(..),FoldM(..)) import qualified Control.Foldl as L-import Control.Foldl.Transduce.Internal (Pair(..),Trio(..))+import Control.Foldl.Transduce.Internal (Pair(..),Trio(..),fstOf3)  {- $setup @@ -105,32 +104,49 @@ -} 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-    downstream.+{-| A stateful process that transforms a stream of inputs into a stream of+    outputs, and may optionally demarcate groups in the stream of outputs. +    Composed of a step function, an initial state, and a extraction function. ++    The step function returns a triplet of:++    * The new internal state.+    * Outputs that continues the last segment detected in the previous step.+    * A list of lists containing outputs for segments detected in the current+    step. If the list is empty, that means no splitting has taken place in the+    current step. 'Transducer's that do not perform grouping never return anything+    other than @[]@ here. In effect, they treat the whole stream as a single group.++    The extraction function returns the 'Transducer's own result value, as+    well as any pending outputs. -} data Transducer i o r-     = forall x. Transducer (x -> i -> (x,[o])) x (x -> (r,[o]))+     = forall x. Transducer (x -> i -> (x,[o],[[o]])) x (x -> (r,[o]))  instance Functor (Transducer i o) where     fmap f (Transducer step begin done) = Transducer step begin (first f . done)  instance Bifunctor (Transducer i) where     first f (Transducer step begin done) =-        Transducer (fmap (fmap (fmap f)) . step) begin (fmap (fmap f) . done)+        Transducer (fmap (\(x,xs,xss) -> (x,map f xs, map (map f) xss)) . step) begin (fmap (fmap f) . done)     second f w = fmap f w +{-| Like 'Transduction', but works on monadic 'Fold's.		++-} type TransductionM m a b = forall x. Monad m => FoldM m b x -> FoldM m a x +{-| Like 'Transduction'', but works on monadic 'Fold's.		++-} type TransductionM' m a b r = forall x. FoldM m b x -> FoldM m a (r,x)  {-| Like 'Transducer', but monadic.  -} data TransducerM m i o r-     = forall x. TransducerM (x -> i -> m (x,[o])) (m x) (x -> m (r,[o]))+     = forall x. TransducerM (x -> i -> m (x,[o],[[o]])) (m x) (x -> m (r,[o]))  instance Monad m => Functor (TransducerM m i o) where     fmap f (TransducerM step begin done) = TransducerM step begin done'@@ -142,13 +158,13 @@  instance (Functor m, Monad m) => Bifunctor (TransducerM m i) where     first f (TransducerM step begin done) =-        TransducerM (fmap (fmap (fmap (fmap f))) . step) begin (fmap (fmap (fmap f)) . done)+        TransducerM (fmap (fmap (\(x,xs,xss) -> (x,map f xs, map (map f) xss))) . step) begin (fmap (fmap (fmap f)) . done)     second f w = fmap f w  {-| Apply a 'Transducer' to a 'Fold', discarding the return value of the     'Transducer'.		 ->>> L.fold (transduce (Transducer (\_ i -> ((),[i])) () (\_ -> ('r',[]))) L.list) [1..7]+>>> L.fold (transduce (Transducer (\_ i -> ((),[i],[])) () (\_ -> ('r',[]))) L.list) [1..7] [1,2,3,4,5,6,7] -} transduce :: Transducer i o r -> Transduction i o @@ -157,7 +173,7 @@ {-| Generalized version of 'transduce' that preserves the return value of     the 'Transducer'. ->>> L.fold (transduce' (Transducer (\_ i -> ((),[i])) () (\_ -> ('r',[]))) L.list) [1..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 -> Transduction' i o x@@ -165,25 +181,31 @@     Fold step (Pair wstate fstate) done          where             step (Pair ws fs) i = -                let (ws',os) = wstep ws i +                let (ws',os,oss) = wstep ws i                  in-                Pair ws' (foldl' fstep fs os)  +                Pair ws' (foldl' fstep fs (os ++ mconcat oss))               done (Pair ws fs) =                  let (wr,os) = wdone ws                 in                  (,) wr (fdone (foldl' fstep fs os))  +{-| Like 'transduce', but works on monadic 'Fold's.		++-} transduceM :: Monad m => TransducerM m i o r -> TransductionM m i o  transduceM t = fmap snd . (transduceM' t) +{-| Like 'transduce'', but works on monadic 'Fold's.		++-} 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             step (Pair ws fs) i = do-                (ws',os) <- wstep ws i-                fs' <- foldlM fstep fs os+                (ws',os,oss) <- wstep ws i+                fs' <- foldlM fstep fs (os ++ mconcat oss)                 return $! Pair ws' fs'             done (Pair ws fs) = do                 (wr,os) <- wdone ws@@ -204,9 +226,9 @@     Transducer step PrefixPending done      where         step PrefixPending a = -            (PrefixAdded, ps ++ [a])+            (PrefixAdded, ps ++ [a],[])         step PrefixAdded a = -            (PrefixAdded, [a])+            (PrefixAdded, [a],[])         done PrefixPending = ((), ps ++ ss)         done PrefixAdded = ((), ss) @@ -225,9 +247,9 @@     where         step PrefixPending a = do             ps <- fmap toList prefixa-            return (PrefixAdded, ps ++ [a])+            return (PrefixAdded, ps ++ [a],[])         step PrefixAdded a = -            return (PrefixAdded, [a])+            return (PrefixAdded, [a],[])         done PrefixPending = do             ps <- fmap toList prefixa             ss <- fmap toList suffixa@@ -241,9 +263,9 @@ {-| Generalize a 'Transducer' to a 'TransducerM'.		  -}-generalizeTransducer :: Monad m => Transducer i o r -> TransducerM m i o r-generalizeTransducer (Transducer step begin done) = TransducerM step' begin' done'-  where+_generalize :: Monad m => Transducer i o r -> TransducerM m i o r+_generalize (Transducer step begin done) = TransducerM step' begin' done'+    where     step' x a = return (step x a)     begin'    = return  begin     done' x   = return (done x)@@ -251,23 +273,28 @@ {-| Simplify a pure 'TransducerM' to a 'Transducer'.		  -}-simplifyTransducer :: TransducerM Identity i o r -> Transducer i o r-simplifyTransducer (TransducerM step begin done) = Transducer step' begin' done' where+_simplify :: TransducerM Identity i o r -> Transducer i o r+_simplify (TransducerM step begin done) = Transducer step' begin' done' +    where     step' x a = runIdentity (step x a)     begin'    = runIdentity  begin     done' x   = runIdentity (done x) + {-| Transforms a 'Transducer' into a 'Fold' by forgetting about the data sent     downstream.		  -} foldify :: Transducer i o r -> Fold i r foldify (Transducer step begin done) =-    Fold (\x i -> fst (step x i)) begin (\x -> fst (done x))+    Fold (\x i -> fstOf3 (step x i)) begin (\x -> fst (done x)) +{-| Monadic version of 'foldify'.		++-} foldifyM :: Functor m => TransducerM m i o r -> FoldM m i r foldifyM (TransducerM step begin done) =-    FoldM (\x i -> fmap fst (step x i)) begin (\x -> fmap fst (done x))+    FoldM (\x i -> fmap fstOf3 (step x i)) begin (\x -> fmap fst (done x))  {-| Transforms a 'Fold' into a 'Transducer' that sends the return value of the     'Fold' downstream when upstream closes.		@@ -277,14 +304,14 @@ chokepoint (Fold fstep fstate fdone) =     (Transducer wstep fstate wdone)     where-        wstep = \fstate' i -> (fstep fstate' i,[])+        wstep = \fstate' i -> (fstep fstate' i,[],[])         wdone = \fstate' -> ((),[fdone fstate'])  chokepointM :: Applicative m => FoldM m i b -> TransducerM m i b () chokepointM (FoldM fstep fstate fdone) =      (TransducerM wstep fstate wdone)     where-        wstep = \fstate' i -> fmap (\s -> (s,[])) (fstep fstate' i)+        wstep = \fstate' i -> fmap (\s -> (s,[],[])) (fstep fstate' i)         wdone = \fstate' -> fmap (\r -> ((),[r])) (fdone fstate')  @@ -302,58 +329,35 @@  ------------------------------------------------------------------------------ -{-| A procedure for splitting a stream into delimited segments. It is-    composed of a step function, an initial state, and a /done/ function that-    may flush some accumulated output downstream.--    The step function returns a triplet of:--    * The new internal state.-    * Output that continues the last segment detected in the previous step.-    * A list of lists containing new segments detected in the current step. If-      the list is empty, that means no splitting has taken place in the current-      step.--}-data Splitter i-     = forall x. Splitter (x -> i -> (x,[i],[[i]])) x (x -> [i])--{-| Applies a 'Transduction' to all groups detected by a 'Splitter', returning-    a 'Transduction' that works over the undivided stream of inputs.		+{-| Repeatedly applies a 'Transduction' to process each of the groups+    demarcated by a 'Transducer', returning a 'Fold' what works over the+    undivided stream of inputs. The return value of the 'Transducer' is+    discarded.  >>> 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 =-    Fold step (Pair sbegin (t (duplicated f))) done -    where-        step (Pair ss fs) i = -           let -               (ss', oldSplit, newSplits) = sstep ss i-               fs' = foldl' (step' . reset) (step' fs oldSplit) newSplits-           in-           Pair ss' fs'-        step' = L.fold . duplicated-        reset (Fold _ fstate fdone) = -           t (duplicated (fdone fstate)) -        done (Pair ss (Fold fstep fstate fdone)) = -            extract (fdone (foldl' fstep fstate (sdone ss)))+groups :: Transducer i i' r -> Transduction i' b -> Transduction i b +groups splitter transduction oldfold = +    let transduction' = fmap ((,) ()) . transduction+        newfold = groups' splitter L.mconcat transduction' oldfold +    in +    fmap snd newfold -{-| 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.		+{-| Generalized version of 'groups' that preserves the return value of the+    'Transducer'. -    In practice, this function behaves like a combinaton of 'groups' and-    'folds' that works in a single pass.+    A summary value for each group is also calculated. They are aggregated for+    the whole stream, with the help of an auxiliary 'Fold'.  >>> 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>")+(((),["<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 =+groups' :: Transducer i i' s+        -> Fold u v -- ^ auxiliary 'Fold' that aggregates the @u@ values produced for each group+        -> Transduction' i' a u -- ^ repeatedly applied for processing each group+        -> Transduction' i a (s,v) +groups' (Transducer sstep sbegin sdone) summarizer t f =     Fold step (Trio sbegin summarizer (t (duplicated f))) done        where          step (Trio ss summarizer' fs) i = @@ -372,34 +376,31 @@            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)+            let +                (s,xss) = sdone ss+                (u,extract -> x) = fdone (foldl' fstep fstate xss)+            in ((s,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        -    where-        step (Pair ss fs) i = do-             let -                 (ss', oldSplit, newSplits) = sstep ss i-             fs' <- step' fs oldSplit-             fs'' <- foldlM step'' fs' newSplits-             return $! Pair ss' fs''-        step' = L.foldM . duplicated-        step'' = \fs is -> reset fs >>= \fs' -> step' fs' is-        reset (FoldM _ fstate fdone) = -           liftM (t . duplicated) (fstate >>= fdone) -        done (Pair ss (FoldM fstep fstate fdone)) = do-            finalf <- fdone =<< flip (foldlM fstep) (sdone ss) =<< fstate-            L.foldM finalf [] +{-| Monadic version of 'groups'.		 -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        +-}+groupsM :: Monad m => TransducerM m i i' s -> TransductionM m i' b -> TransductionM m i b+groupsM splitter transduction oldfold = +    let transduction' = fmap ((,) ()) . transduction+        newfold = +            groupsM' splitter (L.generalize L.mconcat) transduction' oldfold +    in +    fmap snd newfold++{-| Monadic version of 'groups''.		++-}+groupsM' :: Monad m => TransducerM m i i' s -> FoldM m u v -> TransductionM' m i' a u -> TransductionM' m i a (s,v) +groupsM' (TransducerM sstep sbegin sdone) summarizer t f =+    FoldM step (sbegin >>= \zzz -> return (Trio zzz summarizer (t (duplicated f)))) done             where         step (Trio ss summarizer' fs) i = do-            let -                (ss', oldSplit, newSplits) = sstep ss i+            (ss', oldSplit, newSplits) <- sstep ss i              fs' <- step' fs oldSplit             (summarizer'',fs'') <- foldlM step'' (summarizer',fs') newSplits             return $! Trio ss' summarizer'' fs''@@ -417,21 +418,46 @@            return (u, t . duplicated $ x)          done (Trio ss summarizer' (FoldM fstep fstate fdone)) = do-            (u,finalf) <- fdone =<< flip (foldlM fstep) (sdone ss) =<< fstate+            (s,xss) <- sdone ss+            (u,finalf) <- fdone =<< flip (foldlM fstep) xss =<< fstate             v <- L.foldM summarizer' [u]             r <- L.foldM finalf []-            return (v,r)+            return ((s,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. +{-| Summarizes each of the groups demarcated by the 'Transducer' using a+    'Fold'. +    +    The result value of the 'Transducer' is discarded.  -}-folds :: Splitter i -> Fold i b -> Transduction i b+folds :: Transducer i i' r -> Fold i' b -> Transduction i b folds splitter f = groups splitter (transduce (chokepoint f)) -foldsM :: (Applicative m,Monad m) => Splitter i -> FoldM m i b -> TransductionM m i b+{-| Like 'folds', but preserves the return value of the 'Transducer'.++-}+folds' :: Transducer i i' s -> Fold i' b -> Transduction' i b s+folds' splitter innerfold somefold = +    fmap (bimap fst id) (groups' splitter L.mconcat innertrans somefold)+    where+    innertrans = fmap ((,) ()) . transduce (chokepoint innerfold)++{-| Monadic version of 'folds'.		++-}+foldsM :: (Applicative m,Monad m) => TransducerM m i i' r -> FoldM m i' b -> TransductionM m i b foldsM splitter f = groupsM splitter (transduceM (chokepointM f)) ++{-| Monadic version of 'folds''.		++-}+foldsM' :: (Applicative m,Monad m) => TransducerM m i i' s -> FoldM m i' b -> TransductionM' m i b s+foldsM' splitter innerfold somefold = +    fmap (bimap fst id) (groupsM' splitter (L.generalize L.mconcat) innertrans somefold)+    where+    innertrans = fmap ((,) ()) . transduceM (chokepointM innerfold)+ ------------------------------------------------------------------------------  {-| Splits a stream into chunks of fixed size.		@@ -442,13 +468,13 @@ >>> L.fold (groups (chunksOf 2) (transduce (surround [] [0])) L.list) [1..7] [1,2,0,3,4,0,5,6,0,7,0] -}-chunksOf :: Int -> Splitter a-chunksOf 0 = Splitter (\_ _ -> ((),[],repeat [])) () (error "never happens")-chunksOf groupSize = Splitter step groupSize done +chunksOf :: Int -> Transducer a a ()+chunksOf 0 = Transducer (\_ _ -> ((),[],repeat [])) () (error "never happens")+chunksOf groupSize = Transducer step groupSize done      where         step 0 a = (pred groupSize, [], [[a]])         step i a = (pred i, [a], [])-        done _ = []+        done _ = ((),[])  ------------------------------------------------------------------------------ 
src/Control/Foldl/Transduce/Internal.hs view
@@ -2,9 +2,12 @@         -- * Strict datatypes          Pair(..)     ,   Trio(..)+    ,   fstOf3     ) where  data Pair a b = Pair !a !b  data Trio a b c = Trio !a !b !c +fstOf3 :: (a,b,c) -> a+fstOf3 (x,_,_) = x
src/Control/Foldl/Transduce/Text.hs view
@@ -59,7 +59,7 @@         let              T.Some txt leftovers next' = next i          in-        (Pair leftovers next', [txt])+        (Pair leftovers next',[txt],[])     done (Pair leftovers _) =          if B.null leftovers             then ((), [])@@ -120,7 +120,7 @@                 Left ue -> do                     throwE ue                 Right (T.Some txt leftovers next2) -> do-                    return (Pair leftovers next2, [txt])+                    return (Pair leftovers next2,[txt],[])         done (Pair leftovers _) = do             if B.null leftovers                 then return ((), [])@@ -165,11 +165,11 @@ stripStart :: L.Transducer T.Text T.Text () stripStart = L.Transducer step False done     where-        step True i = (True, [i])+        step True i = (True, [i],[])         step False i =             if blank i -                then (False, [])-                else (True, [T.stripStart i])+                then (False,[],[])+                else (True, [T.stripStart i],[])         done _  = ((),[])  {-| Remove trailing white space from a stream of 'Text'.		@@ -188,8 +188,8 @@         step txts i =             if blank i                 -- dangerous!-                then (i:txts, [])-                else ([i], reverse txts)+                then (i:txts, [], [])+                else ([i], reverse txts, [])         done txts = case reverse txts of             txt : _ -> ((), [T.stripEnd txt])             _ -> ((), [])@@ -202,8 +202,8 @@ >>> L.fold (L.groups lines (transduce newline) L.list) (map T.pack ["line 1\n line 2\n"]) ["line 1","\n"," line 2","\n"] -}-lines :: L.Splitter T.Text-lines = L.Splitter step False done +lines :: L.Transducer T.Text T.Text ()+lines = L.Transducer step False done      where         step previousnl txt | Data.Text.null txt = (previousnl,[],[])          step previousnl txt = do@@ -214,5 +214,5 @@                 (_,[]) -> error "never happens"                 (True,_) -> (lastc, [], map pure txts)                 (False,t:ts) -> (lastc, [t], map pure ts)-        done _ = []+        done _ = ((),[])