<div dir="ltr">Hi,<div>I'll try to explain the meaning of different parts of the comprehension::</div><div><br></div><div><font face="monospace">unique xs = [x | <b><font color="#ff0000">(x,y) <- zip xs [0..]</font></b>, x `notElem` (take y xs)] </font></div><div><font color="#ff0000"><b>this</b></font> part means: consider the couples (x,y) that are output of zip xs [0..]</div><div>for example if xs = [10,20,10,30,30], you are taking [(10,0),(20,1),(10,2),(30,3),(30,4)]</div><div><br></div><div><font face="monospace">unique xs = [x | (x,y) <- zip xs [0..], <b><font color="#0000ff">x `notElem` (take y xs)</font></b>]  <br></font></div><div><b><font color="#0000ff">this</font></b> part means: among the things you considered before (i.e. all the couples obtained before), consider only those that satisfy the property that the first element of (x,y) is not an alement of a certain list (take y xs, i.e. the first y elements of xs).</div><div>So in the example above: </div><div>      is 10 an element of (take 0 xs)=[ ] ? No ----> we consider (10,0)</div><div></div><div>      is 20 an element of (take 1 xs)=[10]? No ----> we consider (20,1)</div><div></div><div>      is 10 an element of (take 2 xs)=[10,20]? Yes ----> we DON'T consider (10,2)</div><div></div><div></div><div>      is 30 an element of (take 3 xs)=[10,20,10]? No ----> we consider (30,3)</div><div></div><div></div><div>      is 30 an element of (take 4 xs)=[10,20,10,30]? Yes ----> we DON'T consider (30,4)</div><div>So we are considering only [(10,0),(20,1),(30,3)]</div><div></div><div></div><div>So as you said this is a refinement of the elements generated by the first generator. A refinement means that some of the elements 

generated before are (possibly) discarded, so you don't obtain a [Bool], but something of the same type of what was generated before, i.e. another [(Eq,Int)] possibly shorter than the previous one.</div><div><br></div><div>Finally</div><div><font face="monospace">unique xs =<b><font color="#ff0000"> </font><font color="#00ff00">[x |</font></b> (x,y) <- zip xs [0..], x `notElem` (take y xs)]  <br></font></div><div><b><font color="#00ff00">this</font></b> part says that, of each couple produced and refined before, you take the first element (that was called x).</div><div>So in the example you get [10,20,30] </div><div><br></div><div>Hope this is clear,</div><div>Ut</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Il giorno dom 26 apr 2020 alle ore 14:51 Ken Overton <<a href="mailto:ken.overton@gmail.com">ken.overton@gmail.com</a>> ha scritto:<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">Hello all,<div><br></div><div>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:<br><br>    unique :: Eq a => [a] -> [a]<br>    unique xs = [x | (x,y) <- zip xs [0..], x `notElem` (take y xs)]<br><br>It's using a list comprehension with multiple 'generators' (hope I have the term correctly). My understanding of multiple generators in a list comprehension is that they refine the results of the previous generator.<br><br>So the first generator should produce [(Eq,Int)] as input to the second generator? And the second generator should produce [Bool]?<br><br>My understanding must be wrong though; how do we end up with just the items where the second generator produced True?<br><br>Thanks,<font color="#888888"><br><div><br></div></font></div><div><br></div>-- <br><div dir="ltr"><div>Ken Overton</div><div>(917) 863-3937</div><div><a href="mailto:ken.overton@gmail.com" target="_blank">ken.overton@gmail.com</a></div><div><br></div></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>