Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><code>hGetContents</code> isn't too lazy, it just needs to be composed with other things appropriately to get the desired effect. Maybe the situation would be clearer if it were were renamed <code>exposeContentsToEvaluationAsNeededForTheRestOfTheAction</code> or just <code>listen</code>. </p> <p><code>withFile</code> opens the file, does something (or nothing, as you please -- exactly what you require of it in any case), and closes the file. </p> <p>It will hardly suffice to bring out all the mysteries of 'lazy IO', but consider now this difference in bracketing</p> <pre><code> good file operation = withFile file ReadMode (hGetContents &gt;=&gt; operation &gt;=&gt; print) bad file operation = (withFile file ReadMode hGetContents) &gt;&gt;= operation &gt;&gt;= print -- *Main&gt; good "lazyio.hs" (return . length) -- 503 -- *Main&gt; bad "lazyio.hs" (return . length) -- 0 </code></pre> <p>Crudely put, <code>bad</code> opens and closes the file before it does anything; <code>good</code> does everything in between opening and closing the file. Your first action was akin to <code>bad</code>. <code>withFile</code> should govern all of the action you want done that that depends on the handle. </p> <p>You don't need a strictness enforcer if you are working with <code>String</code>, small files, etc., just an idea how the composition works. Again, in <code>bad</code> all I 'do' before closing the file is <code>exposeContentsToEvaluationAsNeededForTheRestOfTheAction</code>. In <code>good</code> I compose <code>exposeContentsToEvaluationAsNeededForTheRestOfTheAction</code> with the rest of the action I have in mind, then close the file.</p> <p>The familiar <code>length</code> + <code>seq</code> trick mentioned by Patrick, or <code>length</code> + <code>evaluate</code> is worth knowing; your second action with <code>putStrLn txt</code> was a variant. But reorganization is better, unless lazy IO is wrong for your case. </p> <pre><code>$ time ./bad bad: Prelude.last: empty list -- no, lots of Chars there real 0m0.087s $ time ./good '\n' -- right () real 0m15.977s $ time ./seqing Killed -- hopeless, attempting to represent the file contents real 1m54.065s -- in memory as a linked list, before finding out the last char </code></pre> <p>It goes without saying that ByteString and Text are worth knowing about, but reorganization with evaluation in mind is better, since even with them the Lazy variants are often what you need, and they then involve grasping the same distinctions between forms of composition. If you are dealing with one of the (immense) class of cases where this sort of IO is inappropriate, take a look at <code>enumerator</code>, <code>conduit</code> and co., all wonderful.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload