[Haskell-cafe] Simple network client

Jules Bean jules at jellybean.co.uk
Wed Jan 30 13:00:02 EST 2008


Judah Jacobson wrote:
> On Jan 30, 2008 8:31 AM, Bryan O'Sullivan <bos at serpentine.com> wrote:
>> 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.
>> [...]
>> You need to float the call to seq out so that it's evaluated before the
>> call to writeFile:
>>
>>   length cs `seq` writeFile cs
>>
> 
> Another way of doing things: I've recently become a fan of
> Control.Exception.evaluate:
> 
> main = do
>   cs <- readFile "L:/Foo.txt"
>   evalute (length cs)
>   writeFile "L:/Foo.txt" cs
> 
> This might be easier for beginners to understand than messing around
> with seq's (as long as you're already in the IO monad).


And even better is

main = do
   cs <- strictReadFile "L:/Foo.txt"
   writeFile "L:/Foo.txt" cs

which can be rewritten as

main = writeFile "L:/Foo.txt" =<< strictReadFile "L:/Foo.txt"

if you like such things.

The problem is that strictReadFile isn't in the standard lib. My opinion 
is that readFile should *be* strict, and the lazy version should be an 
option with caveats.

In bos's notation, I'd say that readFile should be strict, and on level 
1. It does what people expect. Sure it runs out of memory if the file is 
very big, but I don't find that unexpected. lazyReadFile can go on level 
2 after the boss.

Jules


More information about the Haskell-Cafe mailing list