<div dir="ltr">Glad it helped! You might also be interested in the forums at <a href="https://discourse.haskell.org/">https://discourse.haskell.org/</a> - there is a dedicated learning topic, which has a question at a bunch of different levels including very beginning.<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Apr 10, 2021 at 9:49 AM Galaxy Being <<a href="mailto:borgauf@gmail.com">borgauf@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">So the <font face="monospace">Bool</font> predicates and the generators are not purposefully grouped separately -- it just appears that way from the simplistic beginner book examples. But the evaluation is, indeed, left-to-right in that the first example above has <font face="monospace">even x</font> evaluated directly after <font face="monospace">x <- [1,3]</font>, whereas in the second example the <font face="monospace">y <- undefined</font> is evaluated directly after <font face="monospace">x <- [1,3]</font>, then the <font face="monospace">even x</font>, correct? Again, the beginner book examples give the impression that any and all predicates are A) always pushed to the far right, closest to the right bracket, and B) follow no order of application such as being bound to the form closest to the left. So yes, it's visually obvious that there is an outer-inner looping happening when you see the output of two generators doing combinations, but, again, the beginner treatments I've seen make no explicit mention of order in an LC. This is all news to me, but thanks! That's what these forums are for!<div><br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Apr 10, 2021 at 12:18 AM Matthew Low <<a href="mailto:mlow@ualberta.ca" target="_blank">mlow@ualberta.ca</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">First, I'm confused about what is the input and what is the predicate</blockquote><div>The haskell 2010 report (<a href="https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-420003.11" target="_blank">https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-420003.11</a>) says that after the | we can have any type of qualifier, which can be 1. a generator (I think you called this the input) 2. a local binding (we don't care about these in your example, there are none) or 3. boolean guards, which are any expression that evaluate to Bool (your predicates). So there isn't really a `predicate postion`, predicates can occur anywhere after the `|`.</div><div><br></div><div>As for the behaviour, its easiest to see what happens with a regular list of inputs:</div><div><br></div><div>λ> [(x,y) | x <- [1,2], y <- ['A', 'B']]<br>[(1,'A'),(1,'B'),(2,'A'),(2,'B')]<br></div><div><br></div><div>so `y` acts as an inner loop and `x` the outer.<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><font face="monospace">> [1 | x <- [1,3], even x, y <- undefined]</font></div></blockquote><div>Here we start the outer loop over x, and only if x is even, then we loop over y. But x is never even, so we never loop over y, so we never evaluate `undefined` (Haskell is lazy). So essentially filter out all elements of x and are left with []</div><div><font face="monospace"><br></font></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><font face="monospace">> [1 | x <- [1,3], y <- undefined, even x]</font></div></blockquote><div>Now we've moved the guard into the inner loop, after we try to evaluate y. So we blow up trying to do that and GHCi catches the exception</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><font face="monospace">[1 | x <- [1,3], y <- [1..], even x]</font></div></blockquote><div>Similar to the above, the (even x) isn't guarding the evaluation of y, so we're stuck generating all the infinite pairings of x = 1, y = 1... <br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Apr 9, 2021 at 9:59 PM Galaxy Being <<a href="mailto:borgauf@gmail.com" target="_blank">borgauf@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">I'm looking at Bird's <i>Thinking Functionally with Haskell </i>and he gives two list comprehensions, asking under what conditions they deliver the same results<div><br></div><div><font face="monospace">[e | x <- xs, p x, y <- ys]<br>[e | x <- xs, y <- ys, p x]</font><br></div><div><br></div><div>First, I'm confused about what is the input and what is the predicate. The <font face="monospace">y <- ys</font> in the first LC seems to be in a predicate position, and in the second it's a second input after <font face="monospace">x <- xs</font> with <font face="monospace">p x</font> in the predicate position . . . confusing me.</div><div><br></div><div>The answer examples Bird gives are beyond me:</div><div><br></div><div>They deliver the same result only if ys is a finite list:</div><div><br></div><div><font face="monospace">> [1 | x <- [1,3], even x, y <- undefined]<br></font></div><div><font face="monospace">[]</font></div><div><font face="monospace">> [1 | x <- [1,3], y <- undefined, even x]<br></font></div><div><font face="monospace">Exception: Prelude.undefined<br></font></div><div><font face="monospace">> [1 | x <- [1,3], y <- [1..], even x]</font></div><div><font face="monospace">{Interruped}</font></div><div><br></div><div>I'm not sure what's being said here, or what points are being made.</div><div><br></div></div>
_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
</blockquote></div>
_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
</blockquote></div>
_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
</blockquote></div>