Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I would argue that trying to care about evaluation order is counter productive in Haskell. Not only is the language designed to make evaluation order irrelevant but the evaluation order can jump all over the place in strange and confusing ways. Additionally, the implementation has substantial freedom to execute things differently[1] or to vastly restructure your program[2] if the end result is still the same so different parts of the program might be evaluated in different ways.</p> <p>The only real restriction is what evaluation strategies you <em>can't</em> use. For example, you can't always use strict evaluation because that would cause valid programs to crash or enter infinite loops.</p> <pre><code>const 17 undefined take 10 (repeat 17) </code></pre> <p>That said, if you really care, one valid strategy you could possibly use to implement all of Haskell is lazy evaluation with thunks. Each value is represented in a box that either contains the value or a thunk subroutine that can be used to compute the value when you finally need to use it.</p> <p>So when you write </p> <pre><code>let xs = 1 : [] </code></pre> <p>You would be kind of doing this:</p> <pre class="lang-none prettyprint-override"><code>x --&gt; {thunk} </code></pre> <p>If you never inspect the contents of x then the thunk stays unevaluated. However, if you ever do some pattern matching on the thunk then you need to evaluate the thunk to see what branch you take:</p> <pre><code>case xs of [] -&gt; ... (y:ys) -&gt; ... </code></pre> <p>Now, x's thunk is evaluated and the resulting value is stored in the box in case you ever need it. This is to avoid needing to recompute the thunk. Note that in the following diagram I'm using <code>Cons</code> to stand for the <code>:</code> list constructor</p> <pre class="lang-none prettyprint-override"><code>x ---&gt; {Cons {thunk} {thunk}} ^ ^ | | y ys </code></pre> <p>Of course, just the presence of the pattern math isn't enough you need first be forced to evaluate that pattern match in the first place. Ultimately, this boils down to your main function needing to print a value or something like that.</p> <p>Another thing to point out is that we didn't immediately evaluate the contents of the Cons constructor when we first evaluate it. You can check this by running a program that doesn't use the contents of the list:</p> <pre><code>length [undefined, undefined] </code></pre> <p>Of course, when we actually use <code>y</code> for something then its corresponding thunk gets evaluated.</p> <p>Additionally, you can use bang patterns to mark constructor fields as strict so they get immediately evaluated when the constructor gets evaluated (I don't remember if you need to turn an extension for this though)</p> <pre><code>data LazyBox = LazyBox Int data StrictBox = StrictBox !Int case (LazyBox undefined) of (LazyBox _) -&gt; 17 -- Gives 17 case (StrictBox undefined) of (StrictBox _) -&gt; 17 -- *** Exception: Prelude.undefined </code></pre> <hr> <p>[1]: One important optimization that GHC does is using strict evaluation in the sections that the strictness analyzers determines to be strict.</p> <p>[2]: One of the most radical examples would be <a href="http://www.haskell.org/haskellwiki/Short_cut_fusion" rel="nofollow noreferrer">deforestation</a>.</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. 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