[Haskell-beginners] Question about IO, particularly hGetContents

Ken Overton koverton at lab49.com
Thu Apr 1 23:06:09 EDT 2010


Thanks for the explanation and the warning about hClose.  I thought that using do{} blocks forced lazy evaluations?

________________________________________
From: Isaac Dupree [ml at isaac.cedarswampstudios.org]
Sent: Thursday, April 01, 2010 9:22 PM
To: Ken Overton
Cc: beginners at haskell.org
Subject: Re: [Haskell-beginners] Question about IO, particularly hGetContents

On 04/01/10 21:06, Ken Overton wrote:
> Hello all, I was playing with some Haskell code that read in text files and processed them and often found myself writing empty result-files.  I've pared the problem down to the following small example.
>
> -- example program
> import IO
> main = do
>      rhdl<- openFile "test.in" ReadMode
>      content<- hGetContents rhdl
>      putStrLn content  -- if I cmt out this line, content will be empty
>      hClose rhdl
>      putStrLn "Content: "
>      putStrLn content      -- if the first 'putStrLn' call was commented, this will print a blank line
> -- end example
>
> For some reason, if I comment out the 'putStrLn content' between hGetContents and hClose, the data from the hGetContents call is not stored.  Can somebody verify this behavior and (if so) explain why it's happening?

Yes.  hGetContents retrieves the contents "lazily", only reading them
when demanded by the program*.  When it's read all the contents, it
automatically closes the file, so you shouldn't use hClose in
combination with it (also it stops any future reading from happening,
which is why your program broke).

*implemented using the somewhat controversial "unsafeInterleaveIO". Some
people believe that lazy IO like this is not a good idea, for reasons
similar to the one you encountered, but in circumstances that are harder
to fix.

-Isaac


More information about the Beginners mailing list