
Judah Jacobson wrote:
On Jan 30, 2008 8:31 AM, Bryan O'Sullivan
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