[Haskell-beginners] Strange use of undefined (et al.) in list comprehension

Matthew Low mlow at ualberta.ca
Sat Apr 10 19:26:08 UTC 2021


I missed this question:

> But the evaluation is, indeed, left-to-right ... correct?
Correct (though note that in the second example, evaluating y <- undefined
will throw and exception so (even x) will not be evaluated)

On Sat, Apr 10, 2021 at 1:19 PM Matthew Low <mlow at ualberta.ca> wrote:

> Glad it helped! You might also be interested in the forums at
> https://discourse.haskell.org/ - there is a dedicated learning topic,
> which has a question at a bunch of different levels including very
> beginning.
>
> On Sat, Apr 10, 2021 at 9:49 AM Galaxy Being <borgauf at gmail.com> wrote:
>
>> So the Bool 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 even x evaluated directly after x <- [1,3], whereas in
>> the second example the y <- undefined is evaluated directly after x <-
>> [1,3], then the even x, 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!
>>
>>
>>
>> On Sat, Apr 10, 2021 at 12:18 AM Matthew Low <mlow at ualberta.ca> wrote:
>>
>>> First, I'm confused about what is the input and what is the predicate
>>>
>>> The haskell 2010 report (
>>> https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-420003.11)
>>> 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
>>> `|`.
>>>
>>> As for the behaviour, its easiest to see what happens with a regular
>>> list of inputs:
>>>
>>> λ> [(x,y) | x <- [1,2], y <- ['A', 'B']]
>>> [(1,'A'),(1,'B'),(2,'A'),(2,'B')]
>>>
>>> so `y` acts as an inner loop and `x` the outer.
>>>
>>> > [1 | x <- [1,3], even x, y <- undefined]
>>>>
>>> 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 []
>>>
>>> > [1 | x <- [1,3], y <- undefined, even x]
>>>>
>>> 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
>>>
>>> [1 | x <- [1,3], y <- [1..], even x]
>>>>
>>> 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...
>>>
>>> On Fri, Apr 9, 2021 at 9:59 PM Galaxy Being <borgauf at gmail.com> wrote:
>>>
>>>> I'm looking at Bird's *Thinking Functionally with Haskell *and he
>>>> gives two list comprehensions, asking under what conditions they deliver
>>>> the same results
>>>>
>>>> [e | x <- xs, p x, y <- ys]
>>>> [e | x <- xs, y <- ys, p x]
>>>>
>>>> First, I'm confused about what is the input and what is the predicate.
>>>> The y <- ys in the first LC seems to be in a predicate position, and
>>>> in the second it's a second input after x <- xs with p x in the
>>>> predicate position . . . confusing me.
>>>>
>>>> The answer examples Bird gives are beyond me:
>>>>
>>>> They deliver the same result only if ys is a finite list:
>>>>
>>>> > [1 | x <- [1,3], even x, y <- undefined]
>>>> []
>>>> > [1 | x <- [1,3], y <- undefined, even x]
>>>> Exception: Prelude.undefined
>>>> > [1 | x <- [1,3], y <- [1..], even x]
>>>> {Interruped}
>>>>
>>>> I'm not sure what's being said here, or what points are being made.
>>>>
>>>> _______________________________________________
>>>> Beginners mailing list
>>>> Beginners at haskell.org
>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>>>>
>>> _______________________________________________
>>> Beginners mailing list
>>> Beginners at haskell.org
>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>>>
>> _______________________________________________
>> Beginners mailing list
>> Beginners at haskell.org
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/beginners/attachments/20210410/07c823fa/attachment-0001.html>


More information about the Beginners mailing list