
Some care is required to use withFile properly with lazy IO, and people sometimes get it wrong. In some cases, readFile is a suitable replacement. In other cases, however, it may be necessary to ensure the file gets closed in a timely manner, and it may not be necessary to read the whole file. The following seems to do the trick: safeWithFile :: (NFData a) => String -> IOMode -> (Handle -> IO a) -> IO a safeWithFile name mode f = withFile name mode $ f >=> (return $!!) Sample use: *SafeWithFile> safeWithFile "SafeWithFile.hs" ReadMode hGetContents >>= putStr module SafeWithFile (safeWithFile) where import Control.DeepSeq import System.IO import Control.Monad safeWithFile :: (NFData a) => String -> IOMode -> (Handle -> IO a) -> IO a safeWithFile name mode f = withFile name mode $ f >=> (return $!!)