How do laziness and I/O work together in Haskell?

Posted by Bill on Stack Overflow See other posts from Stack Overflow or by Bill
Published on 2010-05-06T00:47:38Z Indexed on 2010/05/06 1:28 UTC
Read the original article Hit count: 372

Filed under:
|

I'm trying to get a deeper understanding of laziness in Haskell.

I was imagining the following snippet today:

data Image = Image { name :: String, pixels :: String }

image :: String -> IO Image
image path = Image path <$> readFile path

The appeal here is that I could simply create an Image instance and pass it around; if I need the image data it would be read lazily - if not, the time and memory cost of reading the file would be avoided:

 main = do
   image <- image "file"
   putStrLn $ length $ pixels image

But is that how it actually works? How is laziness compatible with IO? Will readFile be called regardless of whether I access pixels image or will the runtime leave that thunk unevaluated if I never refer to it?

If the image is indeed read lazily, then isn't it possible I/O actions could occur out of order? For example, what if immediately after calling image I delete the file? Now the putStrLn call will find nothing when it tries to read.

© Stack Overflow or respective owner

Related posts about haskell

Related posts about laziness