
David Place wrote:
So, the type of your withFile would be
withFile :: FilePath -> IOMode -> (Handle -> IO ()) -> IO ()
completely prohibiting return values from withFile? Sounds good. In that case, you don't need to change the behavior of withFile at all, just its type.
Actually, the type is withFile :: FilePath -> (String -> IO a) -> IO a There is still a return value, but withFile makes sure that it's evaluated to WHNF. If you choose a = (), then you're fine, otherwise it's not entirely foolproof.
It's hGetContents that bothers me. I have found that friends who I have convinced to learn Haskell always trip over this right away. They want to write a simple program that processes a file and immediately get tangled up with lazy IO and looking up the definition of deepseq. It's kind of embarrassing. Sadly, they never pick creating beautiful, incremental lazy algorithms with sharing as their "Hello World" projects.
That's why I usually only teach readFile and writeFile in the beginning. By the way, from a Haskell point of view, it's the operating system that is being unreasonable here, not the other way round. :D Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com