haskell - Is there a way to split an InputStream? -
i wonder if there way "split"/"duplicate" system.io.streams.inputstream
io-streams
package forwarded 2 processing stages?
duplicate :: inputstream -> io (inputstream a, inputstream a)
i can see doesn't work demand driven nature of streams, canonical solution if need several things processed? build pipeline "writes side"? like:
input >>= countevents countioref >>= logevents loggerref >>= output
i go arrow
route , store in tuples, going dirty , knowledge there no arrow interface io-streams
:
input >>= (countevents *** logevents) >>= output
any recommendations?
you can number of ways, since countevents
, logevents
both folds on stream, repeated applications of outputfoldm
simplest. aren't looking way split stream way link folds. outputfoldm
turns stream new stream associated result of applying repeated fold operation it, writing result 'to side' say.
>>> let logger = ios.inputfoldm (\() x -> print x >> putstrln "----") () >>> let counter = ios.inputfoldm (\a _ -> return $! + 1) (0::int) >>> ls0 <- ios.fromlist [1..5::int] >>> (ls1,io_count) <- counter ls0 >>> (ls2,_) <- logger ls1 >>> ios.fold (+) 0 ls2 1 -- here see "logging" happening `logger` ---- 2 ---- 3 ---- 4 ---- 5 ---- 15 -- sum `fold (+) 0` exhausted stream >>> io_count 5 -- result of `counter`
for it's worth, wrote patch make possible apply fold
s , foldm
s foldl
library inputstreams
https://github.com/snapframework/io-streams/issues/53 . permit apply indefinitely many simultaneous folds, discriminating elements please lens, fitting arrow analogy mention. here's same folds/sinks applied way. used applicativedo
write 1 big fold "logging" , collects statistics , formats them. same thing can written applicative operators.
{-#language applicativedo #-} import qualified system.io.streams ios import qualified control.foldl l import control.lens (filtered) main = ls <- ios.fromlist [1..5::int] res <- l.impurely ios.foldm_ myfolds ls putstrln res myfolds = sum_ <- l.generalize l.sum -- generalize makes 'impure' fold length_ <- l.generalize l.length -- out of pure 1 sum or length odd_length_ <- l.generalize (l.handles (filtered odd) l.length) _ <- l.sink (\n -> print n >> putstrln "-------") pure (format sum_ length_ odd_length_) format sum_ length_ odd_length_ = unlines [ "" , "results:" , "sum: " ++ show sum_ , "length: " ++ show length_ , "number odd: " ++ show odd_length_]
so looks this
>>> main 1 ------- 2 ------- 3 ------- 4 ------- 5 ------- results: sum: 15 length: 5 number odd: 3
the "beautiful folding" folds ones in foldl
nice since not special given framework. can apply myfolds
without alteration list, sequence
, unboxed vector, pipes producer
, conduit source
etc etc.. it's separate discipline of hyper-composable folds , sinks.
Comments
Post a Comment