zip package:streaming

Zip two Streams
Zip two streams together. The zipsWith' function should generally be preferred for efficiency.
Zip two streams together.
Zip three Streams together
Zip two Streams using the provided combining function
Zip three Streams with a combining function
The type
Data.List.unzip     :: [(a,b)] -> ([a],[b])
might lead us to expect
Streaming.unzip :: Stream (Of (a,b)) m r -> Stream (Of a) m (Stream (Of b) m r)
which would not stream, since it would have to accumulate the second stream (of bs). Of course, Data.List unzip doesn't stream either. This unzip does stream, though of course you can spoil this by using e.g. toList:
>>> let xs = Prelude.map (\x -> (x, Prelude.show x)) [1..5 :: Int]
>>> S.toList $ S.toList $ S.unzip (S.each xs)
["1","2","3","4","5"] :> ([1,2,3,4,5] :> ())
>>> Prelude.unzip xs
([1,2,3,4,5],["1","2","3","4","5"])
Note the difference of order in the results. It may be of some use to think why. The first application of toList was applied to a stream of integers:
>>> :t S.unzip $ S.each xs
S.unzip $ S.each xs :: Monad m => Stream (Of Int) (Stream (Of String) m) ()
Like any fold, toList takes no notice of the monad of effects.
toList :: Monad m => Stream (Of a) m r -> m (Of [a] r)
In the case at hand (since I am in ghci) m = Stream (Of String) IO. So when I apply toList, I exhaust that stream of integers, folding it into a list:
>>> :t S.toList $ S.unzip $ S.each xs
S.toList $ S.unzip $ S.each xs
:: Monad m => Stream (Of String) m (Of [Int] ())
When I apply toList to this, I reduce everything to an ordinary action in IO, and return a list of strings:
>>> S.toList $ S.toList $ S.unzip (S.each xs)
["1","2","3","4","5"] :> ([1,2,3,4,5] :> ())
unzip can be considered a special case of either unzips or expand:
unzip = unzips . maps (\((a,b) :> x) -> Compose (a :> b :> x))
unzip = expand $ \p ((a,b) :> abs) -> b :> p (a :> abs)