
Thank you all for your answers. I'll try to be more careful with lazy evaluations while doing IO operations from now on. Best regards André
On Fri, Aug 12, 2005 at 02:54:03PM +0200, Lemmih wrote:
On 8/12/05, David Roundy
wrote: On Fri, Aug 12, 2005 at 09:17:32AM -0300, Andr Vargas Abs da Cruz wrote:
readDataFromFile filename = do bracket (openFile filename ReadMode) hClose (\h -> do contents <- hGetContents h return (lines contents))
The question is: if i try to run this, it returns me nothing (just an empty list). Why does this happen ? When i remove the "return" and put a "print" instead, it prints everything as i expected.
I think that this may be because hGetContents puts the file in a semi-closed state (and reads the contents lazily). Try removing the hClose (replacing it with (return ()). Lazy IO is nice, but gets tricky at times.
Or better yet, use 'readFile'.
Indeed, that would be simpler, but it's still lazy IO, and if you're unaware of that you'll still get confused when you try to delete the file after reading the lines you wanted out of it, and it fails on windows, but not on POSIX systems... unless you read the entire file, or computed its length.
Glynn Clements wrote:
hGetContents reads the file lazily; it won't actually read anything until you try to "consume" the result. However, by that point, you will have called hClose.
In general, you shouldn't use hClose in conjunction with lazy I/O (hGetContents etc) unless you are certain that the data will have been read.
When you put the "print" in place of the return, you force the data to be consumed immediately, so the issue doesn't arise.
Arthur Baars wrote: Hi André,
The problem is that hGetContents does lazy reading of the handle.
I you do: readDataFromFile "test.txt" >>= print
the handle is closed by hClose (in readDataFromFile) before "print" demands the contents from the handle.
Just don't close the Handle explicitly. This code works: readDataFromFile filename = do h <-openFile filename ReadMode contents <- hGetContents h return (lines contents)
You do not really need to close it, because hGetContents "semi-closes" the handle. Read more: http://www.haskell.org/onlinereport/io.html (Section 21.2.2 Semi-Closed Handles) http://users.aber.ac.uk/afc/stricthaskell.html#semiclosed
Cheers,
Arthur