[Haskell-beginners] Buggy behavior of "withFile"

Zach Moazeni zach.lists at gmail.com
Sat Dec 13 18:21:33 UTC 2014


I ran into this issue recently for some code that needed to both read and
then later write to the same file. readFile didn't work as expected because
it kept the file handle open. I could restructure the code so the entire
logic was in inside a `withFile` block, but I preferred not to.

I wrote something similar to Zoran's original code and was stumped until I
googled around.  I want to share this stackoverflow answer regarding
deepseq to force evaluation http://stackoverflow.com/a/9423349 (the key
takeaway being `return $!! res` for Zoran's code)

But really, the default built-in lazy I/O on standard lists are fine for
> general usage. Avoid premature optimization.


I agree with Kim here, so I'm not contradicting that sentiment. It's just
nice to know the next step to take if the original lazy I/O code isn't
working out.


On Fri, Dec 12, 2014 at 3:36 AM, Kim-Ee Yeoh <ky3 at atamo.com> wrote:
>
>
> On Wed, Dec 10, 2014 at 3:36 AM, Mike Meyer <mwm at mired.org> wrote:
>>
>> If I'm right, you need to force the evaluation of res before the return,
>> with something like "res seq return res" instead of just "return res".  Or
>> use the BangPatterns extension and then write "!res <- hGetContents h"
>
>
> This will read one byte (or none at all if the file is empty).
>
> That one byte will then be displayed by the putStr outside the withFile
> expression. It's a small but noticeable improvement to nothing being
> displayed at all.
>
> Why one byte? Because seq evaluates only to weak head normal form (WHNF),
> which in the case of a list, amounts to determining whether it's [] or
> (x:xs).
>
> You could write
>
> res <- hGetContents h
> evaluate $ length res         -- Control.Exception.evaluate
> return res
>
> but if you're going to do that, you're better off using Strict I/O. And in
> fact, strict _bytestring_ I/O because the spatial footprint of lists is 10x
> bytestrings.
>
> But really, the default built-in lazy I/O on standard lists are fine for
> general usage. Avoid premature optimization.
>
> -- Kim-Ee
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20141213/3134a57f/attachment-0001.html>


More information about the Beginners mailing list