[Haskell-beginners] A Question about withFile

Erlend Hamberg ehamberg at gmail.com
Wed Jul 25 12:44:51 CEST 2012


On 25 July 2012 11:40, Bin Shi <powerman1st at gmail.com> wrote:
> but if I changed to
>
> main = do
>       c <- withFile "a.txt" ReadMode hGetContents
>       putStrLn c
>
> I got just a empty line.
>
> Where am I wrong?

If we look at the type of “withFile” we see that it is

    withFile :: FilePath -> IOMode -> (Handle -> IO r) -> IO r

The important part here is (Handle -> IO r), i.e. a function that
takes a handle as an argument and produces a result of IO r. If we
de-sugar the do-notation in your first example we get

    withFile "a.txt" ReadMode (\h -> hGetContents h >>= \c -> putStrLn c)

Here we see that the “processing function” passed to withFile is (\h
-> hGetContents h >>= \c -> putStrLn c). In your second example, we
get the following:

    withFile "a.txt" ReadMode hGetContents >>= \c -> putStrLn c

which is equivalent to

    (withFile "a.txt" ReadMode hGetContents) >>= \c -> putStrLn c

hGetContents is lazy and won't start reading until its needed. This,
together with the fact that withFile guarantees that the file handle
is closed after it's finished leads to the whole “withFile” call
returning "" which is then printed by putStrLn.

-- 
Erlend Hamberg
ehamberg at gmail.com



More information about the Beginners mailing list