Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The interesting bit I assume is this:</p> <pre><code>toss2Dice = do n &lt;- tossDie m &lt;- tossDie return (n+m) </code></pre> <p>This is somewhat equivalent to the following Python:</p> <pre><code>def toss2dice(): for n in tossDie: for m in tossDie: yield (n+m) </code></pre> <p>When it comes to the list monad, you can view the binding arrows (<code>&lt;-</code>) in do notation as traditional imperative "foreach" loops. Everything after</p> <pre><code>n &lt;- tossDie </code></pre> <p>belongs to the "loop body" of that foreach loop, and so will be evaluated once for every value in <code>tossDie</code> assigned to <code>n</code>.</p> <p>If you want the desugaring from <code>do</code> notation to actual bind operators <code>&gt;&gt;=</code>, it looks like this:</p> <pre><code>toss2Dice = tossDie &gt;&gt;= (\n -&gt; tossDie &gt;&gt;= (\m -&gt; return (n+m) ) ) </code></pre> <p>Notice how the "inner loop body"</p> <pre><code>(\n -&gt; tossDie &gt;&gt;= (\m -&gt; return (n+m) ) ) </code></pre> <p>Will get executed once for every value in <code>tossDie</code>. This is pretty much the equivalent to the nested Python loops.</p> <hr> <p>Technical mumbo-jumbo: The reason you get "foreach" loops from the binding arrows has to do with the particular monad you are working with. The arrows mean different things for different monads, and to know what they mean for a particular monad you have to do some sleuthing and figure out how that monad works in general.</p> <p>The arrows get desugared into calls to the bind operator, <code>&gt;&gt;=</code>, which works differently for different monads as well – this is the reason the bind arrows <code>&lt;-</code> also work differently for different monads!</p> <p>In the case of the list monad, the bind operator <code>&gt;&gt;=</code> takes a list to the left and a function returning a list to the right, and sort of applies that function to every element of the list. If we want to double every element in a list in a cumbersome way, we could imagine doing it as</p> <pre><code>λ&gt; [1, 2, 3, 4] &gt;&gt;= \n -&gt; return (n*2) [2,4,6,8] </code></pre> <p>(<code>return</code> is required to make the types work out. <code>&gt;&gt;=</code> expects a function that returns a list, and <code>return</code> will, for the list monad, wrap a value in a list.) To illustrate a perhaps more powerful example, we can start by imagining the function</p> <pre><code>λ&gt; let posneg n = [n, -n] λ&gt; posneg 5 [5,-5] </code></pre> <p>Then we can write</p> <pre><code>λ&gt; [1, 2, 3, 4] &gt;&gt;= posneg [1,-1,2,-2,3,-3,4,-4] </code></pre> <p>to count the natural numbers between -4 and 4.</p> <p>The reason the list monad works this way is that this particular behaviour of the bind operator <code>&gt;&gt;=</code> and <code>return</code> makes the monad laws hold. The monad laws are important for us (and perhaps the adventurous compiler) because they let us change code in ways that we know will not break anything.</p> <p>A very cute side effect of this is that it makes lists very handy to represent uncertainty in values: Say you are building an OCR thingey that's supposed to look at an image and turn it into text. You might encounter a character that could be either 4 or A or H, but you are not sure. By letting the OCR thingey work in the list monad and return the list <code>['A', '4', 'H']</code> you have covered your bases. Actually working with the scanned text then become very easy and readable with <code>do</code> notation for the list monad. (It sorta looks like you're working with single values, when in fact you are just generating all possible combinations!)</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