Hi William,
> When I run this code, I get one blank line of output. Now, if I uncomment the putStrLn call inside of readEntry, I get the contents of randomfile.txt printed out *twice*.
>
> As far as I can tell, Haskell is not evaluating "content <- hGetContents handle" until I call putStrLn on content. Meanwhile, withFile conveniently closes the input file before putStrLn gets called in main.
>
> So, is there something I am doing here that is fundamentally wrong, or is lazy evaluation just plain stupid and buggy and I should just give up on Haskell already? Seriously, this is ridiculous.
The getContents should come with a big warning. Right now the docs read:
"The getContents operation returns all user input as a single
string, which is read lazily as it is needed (same as hGetContents
stdin). "
You've correctly identified the problem: lazy I/O lazily a bad idea.
The base library should never had included those functions, but that
ship has unfortunately sailed as it's part of the published H98
standard and lots of code already uses those functions.
You can do one of two things here, either read the whole file strictly
(using Data.ByteString.hGetContents or Data.ByteString.readFile) or
explicitly read it chunk-wise, using e.g. Data.ByteString.hGet.
Our base I/O layer is really in need of a face-lift.
Cheers,
Johan