[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