composewell / streamly

High performance, concurrent functional programming abstractions
https://streamly.composewell.com
Other
849 stars 63 forks source link

Contra-flattening a Fold #2734

Open rihardsk opened 3 months ago

rihardsk commented 3 months ago

I hope I'm using the term contravariant here correctly. Basically I want to flatten the inputs of a fold. I.e., I need a function with the following type:

contraFlatten :: Fold m a b -> Fold m [a] b
-- or maybe something more general is possible? e.g.,
-- contraFlatten :: Foldable f => Fold m a b -> Fold m (f a) b

I looked through streamly-core and nothing like this seems to exist?

harendra-kumar commented 3 months ago

You can try unfoldMany internal API. See https://streamly.composewell.com/haddocks/streamly-core-0.2.2/Streamly-Internal-Data-Fold.html#v:unfoldMany . You can pass the Unfold.fromList to it to unfold a list.

The unfoldMany implementation does not fuse though, so if fusion/efficiency is important you cannot use it. Fusing such operation would require changing the type.

rihardsk commented 3 months ago

Thank you!

Maybe it's worth to consider adding something like this as an example?

contraFlatten :: Monad m => Fold m a b -> Fold m [a] b
contraFlatten = unfoldMany fromList

It wasn't obvious to me at first how to use unfoldMany to get what I want.