How to compose operations in streaming

I have a question about the streaming package. Let's say I have str :: Stream (Of String) IO () I want to putStrLn each element and then print the length of str, so I could do this: import Streaming import qualified Streaming.Prelude as SP doit :: Stream (Of String) IO () -> IO () doit str = do SP.mapM_ putStrLn str SP.length_ str >>= print However, will this result in doing 2 passes over str so that the memory requirement is not constant? If so, is there a simple way to combine the two actions so that only pass is needed? I could probably use a counter in a StateT but that's not really simple. More generally, are there techniques for combining folds like how one would with the foldl package?

On Wed, Jun 03, 2020 at 03:04:59PM +0800, ☂Josh Chia (謝任中) wrote:
I want to putStrLn each element and then print the length of str [...] doit :: Stream (Of String) IO () -> IO () doit str = do SP.mapM_ putStrLn str SP.length_ str >>= print
Isn't it SP.length_ (SP.mapM_ putStrLn str) >>= print

The type of "SP.mapM_ putStrLn str" is IO (), so I don't think "SP.length_ (SP.mapM_ putStrLn str)" type checks, unless I'm somehow misreading your code. Anyway, I just realized I can use SP.copy: do l <- SP.mapM_ putStrLn $ SP.length_ $ SP.copy str print l "l <- SP.length_ $ SP.mapM_ putStrLn $ SP.copy str" also works. On Wed, Jun 3, 2020 at 3:23 PM Tom Ellis < tom-lists-haskell-cafe-2017@jaguarpaw.co.uk> wrote:
On Wed, Jun 03, 2020 at 03:04:59PM +0800, ☂Josh Chia (謝任中) wrote:
I want to putStrLn each element and then print the length of str [...] doit :: Stream (Of String) IO () -> IO () doit str = do SP.mapM_ putStrLn str SP.length_ str >>= print
Isn't it
SP.length_ (SP.mapM_ putStrLn str) >>= print _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

On Wed, Jun 03, 2020 at 07:38:51PM +0800, ☂Josh Chia (謝任中) wrote:
The type of "SP.mapM_ putStrLn str" is IO (), so I don't think "SP.length_ (SP.mapM_ putStrLn str)" type checks, unless I'm somehow misreading your code.
I meant `SP.mapM`. This works: doit :: Stream (Of String) IO () -> IO () doit str = SP.length_ (SP.mapM putStrLn str) >>= Prelude.print `copy` is an intruiging solution though!
participants (2)
-
Tom Ellis
-
☂Josh Chia (謝任中)