Send Beginners mailing list submissions to
        beginners@haskell.org

To subscribe or unsubscribe via the World Wide Web, visit
        http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
        beginners-requ...@haskell.org

You can reach the person managing the list at
        beginners-ow...@haskell.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1.  List comprehensions with multiple generators (Ken Overton)
   2. Re:  List comprehensions with multiple generators (Ut Primum)
   3. Re:  List comprehensions with multiple generators
      (Francesco Ariis)
   4. Re:  List comprehensions with multiple generators (Ken Overton)
   5. Re:  List comprehensions with multiple generators
      (Francesco Ariis)


----------------------------------------------------------------------

Message: 1
Date: Sun, 26 Apr 2020 08:50:20 -0400
From: Ken Overton <ken.over...@gmail.com>
To: beginners@haskell.org
Subject: [Haskell-beginners] List comprehensions with multiple
        generators
Message-ID:
        <CA+OPjNvN3r5Jj6092C7+1ia2BC-PEOu-P-J2P7AekECOWx=n...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

Hello all,

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)]

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.

So the first generator should produce [(Eq,Int)] as input to the second
generator? And the second generator should produce [Bool]?

My understanding must be wrong though; how do we end up with just the items
where the second generator produced True?

Thanks,


-- 
Ken Overton
(917) 863-3937
ken.over...@gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://mail.haskell.org/pipermail/beginners/attachments/20200426/801702b5/attachment-0001.html>

------------------------------

Message: 2
Date: Sun, 26 Apr 2020 15:35:55 +0200
From: Ut Primum <utpri...@gmail.com>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <beginners@haskell.org>
Subject: Re: [Haskell-beginners] List comprehensions with multiple
        generators
Message-ID:
        <canjdmkj+bzgrk5ga8kiqpks2oy3redyy5dheha9mcynobdy...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

Hi,
I'll try to explain the meaning of different parts of the comprehension::

unique xs = [x | *(x,y) <- zip xs [0..]*, x `notElem` (take y xs)]
*this* part means: consider the couples (x,y) that are output of zip xs
[0..]
for example if xs = [10,20,10,30,30], you are taking
[(10,0),(20,1),(10,2),(30,3),(30,4)]

unique xs = [x | (x,y) <- zip xs [0..], *x `notElem` (take y xs)*]
*this* 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).
So in the example above:
      is 10 an element of (take 0 xs)=[ ] ? No ----> we consider (10,0)
      is 20 an element of (take 1 xs)=[10]? No ----> we consider (20,1)
      is 10 an element of (take 2 xs)=[10,20]? Yes ----> we DON'T consider
(10,2)
      is 30 an element of (take 3 xs)=[10,20,10]? No ----> we consider
(30,3)
      is 30 an element of (take 4 xs)=[10,20,10,30]? Yes ----> we DON'T
consider (30,4)
So we are considering only [(10,0),(20,1),(30,3)]
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.

Finally
unique xs =* [x |* (x,y) <- zip xs [0..], x `notElem` (take y xs)]
*this* part says that, of each couple produced and refined before, you take
the first element (that was called x).
So in the example you get [10,20,30]

Hope this is clear,
Ut

Il giorno dom 26 apr 2020 alle ore 14:51 Ken Overton <ken.over...@gmail.com>
ha scritto:

> Hello all,
>
> 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)]
>
> 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.
>
> So the first generator should produce [(Eq,Int)] as input to the second
> generator? And the second generator should produce [Bool]?
>
> My understanding must be wrong though; how do we end up with just the
> items where the second generator produced True?
>
> Thanks,
>
>
> --
> Ken Overton
> (917) 863-3937
> ken.over...@gmail.com
>
> _______________________________________________
> Beginners mailing list
> Beginners@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/20200426/1a7deb9d/attachment-0001.html>

------------------------------

Message: 3
Date: Sun, 26 Apr 2020 15:39:13 +0200
From: Francesco Ariis <fa...@ariis.it>
To: beginners@haskell.org
Subject: Re: [Haskell-beginners] List comprehensions with multiple
        generators
Message-ID: <20200426133913.GA25630@extensa>
Content-Type: text/plain; charset=us-ascii

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


------------------------------

Message: 4
Date: Sun, 26 Apr 2020 10:26:48 -0400
From: Ken Overton <ken.over...@gmail.com>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <beginners@haskell.org>
Subject: Re: [Haskell-beginners] List comprehensions with multiple
        generators
Message-ID:
        <CA+OPjNvKyvgEioHj9GkJHvDuaH=yquqwpq2b2zuy9xf4wlj...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

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...@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.over...@gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://mail.haskell.org/pipermail/beginners/attachments/20200426/48d58b93/attachment-0001.html>

------------------------------

Message: 5
Date: Mon, 27 Apr 2020 04:18:07 +0200
From: Francesco Ariis <fa...@ariis.it>
To: beginners@haskell.org
Subject: Re: [Haskell-beginners] List comprehensions with multiple
        generators
Message-ID: <20200427021807.GA21809@extensa>
Content-Type: text/plain; charset=us-ascii

On Sun, Apr 26, 2020 at 10:26:48AM -0400, Ken Overton wrote:
> 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?

I am not sure I understand what you are trying to achieve, but there
is always the possibility of bringing the `y` and the "filter" before
the guard:

    uniqueInternal :: Eq a => [a] -> [(a, Int, Bool)]
    uniqueInternal xs = [(x,y, x `notElem` take y xs) | (x,y) <- zip xs [0..]]



------------------------------

Subject: Digest Footer

_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners


------------------------------

End of Beginners Digest, Vol 142, Issue 5
*****************************************

Reply via email to