[Haskell-beginners] Buggy behavior of "withFile"

Mike Meyer mwm at mired.org
Tue Dec 9 20:36:50 UTC 2014


On Tue, Dec 9, 2014 at 2:21 PM, Zoran Plesivčak <zplesiv at gmail.com> wrote:

> I've encountered unexplainable of "withFile" function. Consider
> "example.hs" program:
>
>     import System.IO
>
>     main = do
>         cnts <- withFile "example.hs" ReadMode $ (\h -> do
>             res <- hGetContents h
>             --putStr res
>             return res)
>         putStr cnts
>
> When commented-out line is like that, program doesn't write out
> anything to the STDOUT.
> If "--" (commend characters) are removed, program writes out contents
> of "example.hs" two times.
>

I'm not an expert, but I believe you're problem is lazy IO. hGetContents
doesn't actually read the file until something consumes it. In the version
with the first putStr commented out, that doesn't happen until you do the
putStr outside the withFile - by which time the file handle has been
closed, so nothing ever gets read.

With the putStr inside the withFile, that consumes the contents before the
file is closed, so it gets read and then returned, where the second putStr
outputs it a second time.

If I'm right, you need to force the evaluation of res before the return,
with something like "res seq return res" instead of just "return res".  Or
use the BangPatterns extension and then write "!res <- hGetContents h"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20141209/834386bc/attachment.html>


More information about the Beginners mailing list