This is a noob question.
I'd like to write a function which provides a lazy stream of images, presumably something like:
imageStream :: [IO Image]
Unfortunately, the function which reads images can fail, so it looks like:
readImage :: IO (Maybe Image)
So, the function I can write looks like:
maybeImageStream :: [IO (Maybe Image)]
How do I implement a function such as the following, while still keeping lazy IO?
flattenImageStream :: [IO (Maybe Image)] -> [IO Image]
Semantically, when you ask flattenImageStream
for the next image, it should iterate through the list and attempt to read each image. It does this until it finds an image that loads, and returns it.
EDIT: There seems to be some disagreement in the answers.
Some have suggested solutions that use sequence
, but I'm pretty sure I tested that and found it destroys laziness.
(I'll test it again to be sure when I get back to my computer.)
Someone also suggested using unsafeInterleaveIO
.
From the documentation for that function, it seems it would work, but obviously I want to respect the type system as much as possible.