Gabriella439 / pipes

Compositional pipelines
BSD 3-Clause "New" or "Revised" License
487 stars 72 forks source link

Helper function to group a pipe into chunks? #190

Closed haasn closed 7 years ago

haasn commented 7 years ago

I'm trying to find a function that allows me to do something with the equivalent of this type signature:

group :: Int -> Pipe a [a] m r

I'm also struggling to try and define this myself. The naive approach that comes to mind is the following:

group n = forever $ replicateM n await >>= yield

But this will fail when the number of values in the input is not a perfect multiple of n, for example:

λ P.toList $ each [1..10] >-> group 3
[[1,2,3],[4,5,6],[7,8,9]]

The last [10] group is omitted here because the await fails before it has a chance to yield the partial list. How do I implement this function in a better way, and is it defined anywhere already?

It seems like it would be useful for a number of things that can process values in batches rather than one-by-one.

Gabriella439 commented 7 years ago

The pipes-group library solves this purpose: https://hackage.haskell.org/package/pipes-group/docs/Pipes-Group-Tutorial.html

However, I strongly recommend using the streaming library which solves this use case better (and is better optimized for it)

haasn commented 7 years ago

Interesting, that one is new to me. It does looks promising.

One of the things in particular that I was going to try combining with pipes is the pipes-concurrency library, although after studying the code a bit I believe I can reimplement the functionality using TQueue on top of streaming without having to incur a pipes dependency.