
Hi, I'm looking at this: data Stream a = Cons a (Stream a) and with streamFromSeed :: (a -> a) -> a -> Stream a streamFromSeed f a = Cons a (streamFromSeed f (f a)) I can do, for example, evens :: Stream Integer evens = streamFromSeed (+2) 0 what I'd like to do is take one item at a time from the stream. My first shot was next :: (Stream a) -> (Stream a, a) but that means I need to keep a ref to the stream that is returned in the tuple which makes for messy code for subsequent calls to next. I sense that the State monad needs to be involved but I'm not sure exactly how as my experiments with State still required I keep a ref to the 'new' stream. Conceptually I see this as a 'global' state and next is just next :: a but that's 30 years of imperative programming speaking and is, I think, wrong! Any help would be really appreciated. Thanks Mike

On Thu, Jul 27, 2017 at 09:33:33AM +0100, mike h wrote:
What I'd like to do is take one item at a time from the stream. My first shot was
next :: (Stream a) -> (Stream a, a)
but that means I need to keep a ref to the stream that is returned in the tuple which makes for messy code for subsequent calls to next. I sense that the State monad needs to be involved but I'm not sure exactly how as my experiments with State still required I keep a ref to the 'new' stream. Conceptually I see this as a 'global' state and next is just
next :: a
but that's 30 years of imperative programming speaking and is, I think, wrong!
Hello Mike, I see nothing wrong with a State monad (you signature looks really like the one inside a State monad, after all) next :: Stream a -> (a, Stream a) next' :: s -> (a, s ) Many many many other ways of dealing elegantly with streams have been proposed; check for example this article [1], which starts exactly from your example, e.g. data Stream b = SCons (b, Stream b) And then, if you are sold to the idea, exploring the various libraries on hackage is the other half of the fun :P -F [1] https://blog.jle.im/entry/intro-to-machines-arrows-part-1-stream-and

Thanks Francesco - I’ll follow up the link. M
On 27 Jul 2017, at 11:08, Francesco Ariis
wrote: On Thu, Jul 27, 2017 at 09:33:33AM +0100, mike h wrote:
What I'd like to do is take one item at a time from the stream. My first shot was
next :: (Stream a) -> (Stream a, a)
but that means I need to keep a ref to the stream that is returned in the tuple which makes for messy code for subsequent calls to next. I sense that the State monad needs to be involved but I'm not sure exactly how as my experiments with State still required I keep a ref to the 'new' stream. Conceptually I see this as a 'global' state and next is just
next :: a
but that's 30 years of imperative programming speaking and is, I think, wrong!
Hello Mike,
I see nothing wrong with a State monad (you signature looks really like the one inside a State monad, after all)
next :: Stream a -> (a, Stream a) next' :: s -> (a, s )
Many many many other ways of dealing elegantly with streams have been proposed; check for example this article [1], which starts exactly from your example, e.g.
data Stream b = SCons (b, Stream b)
And then, if you are sold to the idea, exploring the various libraries on hackage is the other half of the fun :P -F
[1] https://blog.jle.im/entry/intro-to-machines-arrows-part-1-stream-and _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
participants (2)
-
Francesco Ariis
-
mike h