I see now, thanks to both of you; I think I was thrown off by the term 'generators' -- the 'refinement' provided by the second generator is more like filter rather than map.

I guess if I actually wanted the case all the pairs were evaluated and resulted in [Bool] where the first occurrence of an item were True, rather than multiple generators I would have two nested list comprehensions? 

Thanks everyone,

On Sun, Apr 26, 2020 at 9:39 AM Francesco Ariis <fa-ml@ariis.it> wrote:
Hello Ken,

On Sun, Apr 26, 2020 at 08:50:20AM -0400, Ken Overton wrote:
> I recently came across this function which made me realize I don't
> understand list comprehensions well. I hope someone can help me understand
> them better by understanding this example better. The function takes a list
> of Eq and returns the list of unique elements from it:
>
>     unique :: Eq a => [a] -> [a]
>     unique xs = [x | (x,y) <- zip xs [0..], x `notElem` (take y xs)]
>
>
> [...]
>
> So the first generator should produce [(Eq,Int)] as input to the second
> generator? And the second generator should produce [Bool]?

1. (x,y) <- zip xs [0..] -- generates a list of pairs.
2. x `notElem` (take y xs) -- acts like a guard to 1., so only the `x`s
   which are not in the first `y` elements of `xs` (in other words, the
   previous elements of `xs`) will be returned.

The examples on the wiki [1] show more way of using list
comprehensions.

[1] https://wiki.haskell.org/List_comprehension#Examples
_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners


--
Ken Overton
(917) 863-3937
ken.overton@gmail.com