[Haskell-cafe] Newbie question
André Vargas Abs da Cruz
andrev at ele.puc-rio.br
Fri Aug 12 09:14:39 EDT 2005
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 <droundy at darcs.net> 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
More information about the Haskell-Cafe
mailing list