danidiaz
danidiaz

Reputation: 27766

How to implement folds and foldsM from pipes-group for the streaming package?

The pipes-group library lets you delimit groups in effectful streams without having to hold an entire group in memory at any time.

Two useful function from pipes-groups are folds and foldsM:

folds :: Monad m => (x -> a -> x) -> x -> (x -> b) -> FreeT (Producer a m) m r -> Producer b m r

foldsM :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> FreeT (Producer a m) m r -> Producer b m r

They summarize each group within a delimited stream and return a stream of the results.

The streaming package also supports delimited streams, by using the Stream type itself as the functor parameter:

Stream (Stream (Of a) m) m r

There doesn't seem to exist direct analogues of folds and foldsM though. (Folds for undivided streams do exist).

How to implement these functions with the machinery of streaming?

Upvotes: 2

Views: 116

Answers (1)

dfeuer
dfeuer

Reputation: 48631

It looks like Streaming.mapped is the key tool.

mapped :: (Monad m, Functor f)
       => (forall x. f x -> m (g x)) 
       -> Stream f m r
       -> Stream g m r

mapped :: (Monad m, Functor f)
       => (forall x. Stream f m x -> m (g x))
       -> Stream (Stream f m) m r
       -> Stream g m r

mapped :: Monad m
       => (forall x. Stream (Of a) m x -> m (Of b x))
       -> Stream (Stream (Of a) m) m r
       -> Stream (Of b) m r

We also have the relevant provided folds,

fold :: Monad m
     => (x -> a -> x) -> x -> (x -> b)
     -> Stream (Of a) m r -> m (Of b r)

foldM :: Monad m
      => (x -> a -> m x) -> m x -> (x -> m b)
      -> Stream (Of a) m r -> m (Of b r)

So you should be able to apply mapped to a partially applied fold or foldM to produce a stream of summaries.

Caution: I have not yet attempted this.

Upvotes: 2

Related Questions