
Joey Hess
The function below always returns "", rather than the file's contents. _Real World Haskell_ touches on how laziness can make this problimatic, without really giving a solution, other than throwing in a putStr to force evaluation, which can't be done here. How can I make hGetContents strict, to ensure the file contents are really read before it gets closed?
In general you don't want to read a file as a String non-lazily. That uses a lot of memory, because String is just a type alias for [Char], which means a linked list of Char values. To read an entire file eagerly the proper way is in most cases using Data.ByteString or Data.ByteString.Char8, which have a strict interface. A ByteString from those modules is always either non-evaluated or completely evaluated, and it is a real byte array instead of a linked list. Both modules feature hGetContents: import qualified Data.ByteString.Char8 as B readFileLocked :: FilePath -> IO B.ByteString readFileLocked fn = withFile fn ReadMode $ \h -> do lockFile h -- for a suitable function lockFile B.hGetContents h It is, BTW, always preferable to use withFile over openFile, if you can. This makes your code cleaner and also exception-safe. Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/