[Haskell-cafe] Simple network client

Bryan O'Sullivan bos at serpentine.com
Wed Jan 30 11:31:51 EST 2008

Peter Verswyvelen wrote:

> Then I tried the "seq" hack to force the handle opened by readFile to be closed, but that did not seem to work either. For example, the following still gave access denied:
> main = do
>   cs <- readFile "L:/Foo.txt"
>   writeFile "L:/Foo.txt" $ seq (length cs) cs

This is unfortunately a classic beginner's mistake.  You got the seq
wrong here, which is very common.

If you think about the way Haskell evaluates your code, writeFile isn't
going to need the data that it's writing until after it's opened the
file.  Thus the seq won't be reduced until writeFile needs to write the
file.  The file is still open behind the scenes when writeFile begins,
since the contents of cs have not yet been demanded, so writeFile's
attempt to open the file fails.

You need to float the call to seq out so that it's evaluated before the
call to writeFile:

  length cs `seq` writeFile cs

Almost everyone makes this mistake early on.  Quite often, it's
*exactly* this mistake that is made, with just the sequence of
transformations you described.  There's nothing wrong with hGetContents
or readFile.  They just ought to appear on level two, after you've
defeated the lazy evaluation boss at the end of level one.


More information about the Haskell-Cafe mailing list