Hi,
I was watching Rich Hickey's presentations on transducers and decided to implement something like it for foldl folds, as an exercise.
import qualified Control.Foldl as L
import Control.Foldl.Transduce
import Control.Foldl.Transduce.Text
The main types are
type Transduction a b = forall x. Fold b x -> Fold a x
data Transducer i o r
= forall x. Transducer (x -> i -> (x,[o])) x (x -> (r,[o]))
A Transducer is like a Fold that can emit output downstream. A Transducer can be applied to a Fold with the "transduce" function:
transduce :: Transducer i o r -> Transduction i o
A very simple Transducer is "surround" that adds a prefix and a suffix to the stream of data coming to a Fold:
>>> L.fold (transduce (surround "prefix" "suffix") L.list) "middle"
"prefixmiddlesuffix"
Then there's also decoding transducers:
>>> L.fold (transduce utf8lenient L.list) (map fromString ["decode","this"])
["decode","this"]
And also transducer analogues of some functions from pipes-group (they're less powerful though, in that they force you to treat every group the same way):
>>> L.fold (groups (chunksOf 2) (transduce (surround [] [0])) L.list) [1..7]
[1,2,0,3,4,0,5,6,0,7,0]
The existence of pipes makes transducers a bit superflous I suppose. Anyway, once I add some tests and iron out the (very likely) space leaks, I was thinking of putting this on Hackage as foldl-transduce (if Gabriel doesn't mind, I don't want to "name squat" on the foldl-* namespace.)
Any comments or bug reports welcome!