This page is no longer maintained — Please continue to the home page at www.scala-lang.org

flatMap Confusion

3 replies
hossein_haeri
Joined: 2011-09-25,
User offline. Last seen 1 year 2 weeks ago.
Dear all,
Reading Chapter 23 of PinS, I feel I gained some nice introspection into how for expressions are managed in Scala. Yet, I also ended up wrestling with how the yield thing works. Consider the following snippet from S16.7/362:
"The flatMap operator is similar to map, but it takes a function returning a list of elements as its right operand. It applies the function to each list element and returns the concatenation of all function results."
I seem to find that contradictory with the following formal definition (taken from S23.6/529):
def flatMap[A, B](xs: List[A], f: A => List[B]): List[B] = for (x <- xs; y <- f(x)) yield y
Correct me if I'm wrong. But, I think the definition of map given right above that of flatMap above (in the same page of PinS) can be rewritten as:
def map[A, B](xs: List[A], f: A => B): List[B] = for (x <- xs; y <- f(x)) yield y
Then, the only difference I can spot across the above two definitions is that y in flatMap is an instance of List[B] whilst it's of type B in map. Now, I wonder how it is that in the case of flatMap, the same yield expression also performs the concatenation whilst the map one doesn't! Any ideas?
TIA,
--Hossein 
--------------------------------------------------------------------------------------------------------------

Seyed H. HAERI (Hossein)

Research Assistant
Institute for Software Systems (STS)
Technical University of Hamburg (TUHH)
Hamburg, Germany

ACCU - Professionalism in programming - http://www.accu.org/
--------------------------------------------------------------------------------------------------------------
Luc Duponcheel
Joined: 2008-12-19,
User offline. Last seen 34 weeks 3 days ago.
Re: flatMap Confusion
sorry for the somewhat simple reply,
but the difference between map and flatMap
is that, for flatMap, somehow, "sequencing"
of two things is involved, while for map only one,
well, mapping is involved

On Sun, Nov 27, 2011 at 3:41 PM, Seyed H. HAERI (Hossein) <hossein.haeri@gmail.com> wrote:
Dear all,
Reading Chapter 23 of PinS, I feel I gained some nice introspection into how for expressions are managed in Scala. Yet, I also ended up wrestling with how the yield thing works. Consider the following snippet from S16.7/362:
"The flatMap operator is similar to map, but it takes a function returning a list of elements as its right operand. It applies the function to each list element and returns the concatenation of all function results."
I seem to find that contradictory with the following formal definition (taken from S23.6/529):
def flatMap[A, B](xs: List[A], f: A => List[B]): List[B] = for (x <- xs; y <- f(x)) yield y
Correct me if I'm wrong. But, I think the definition of map given right above that of flatMap above (in the same page of PinS) can be rewritten as:
def map[A, B](xs: List[A], f: A => B): List[B] = for (x <- xs; y <- f(x)) yield y
Then, the only difference I can spot across the above two definitions is that y in flatMap is an instance of List[B] whilst it's of type B in map. Now, I wonder how it is that in the case of flatMap, the same yield expression also performs the concatenation whilst the map one doesn't! Any ideas?
TIA,
--Hossein 
--------------------------------------------------------------------------------------------------------------

Seyed H. HAERI (Hossein)

Research Assistant
Institute for Software Systems (STS)
Technical University of Hamburg (TUHH)
Hamburg, Germany

ACCU - Professionalism in programming - http://www.accu.org/
--------------------------------------------------------------------------------------------------------------



--
   __~O
  -\ <,
(*)/ (*)

reality goes far beyond imagination

Joshua.Suereth
Joined: 2008-09-02,
User offline. Last seen 32 weeks 6 days ago.
Re: flatMap Confusion


On Sun, Nov 27, 2011 at 9:41 AM, Seyed H. HAERI (Hossein) <hossein.haeri@gmail.com> wrote:
Dear all,
Reading Chapter 23 of PinS, I feel I gained some nice introspection into how for expressions are managed in Scala. Yet, I also ended up wrestling with how the yield thing works. Consider the following snippet from S16.7/362:
"The flatMap operator is similar to map, but it takes a function returning a list of elements as its right operand. It applies the function to each list element and returns the concatenation of all function results."
I seem to find that contradictory with the following formal definition (taken from S23.6/529):
def flatMap[A, B](xs: List[A], f: A => List[B]): List[B] = for (x <- xs; y <- f(x)) yield y
Correct me if I'm wrong. But, I think the definition of map given right above that of flatMap above (in the same page of PinS) can be rewritten as:
def map[A, B](xs: List[A], f: A => B): List[B] = for (x <- xs; y <- f(x)) yield y

This is not the case.  You can't run a generator on something that is not a "collection-ish" i.e. you mean:
for(x <- xs) yield f(x)  // A Map operation.
*or*
for {  x <- xs  y = f(x)} yield y   // Still a map.

What may boggle the mind is that a for-expression *is implemented using* the map and flatMap methods.  


Then, the only difference I can spot across the above two definitions is that y in flatMap is an instance of List[B] whilst it's of type B in map. Now, I wonder how it is that in the case of flatMap, the same yield expression also performs the concatenation whilst the map one doesn't! Any ideas?
TIA,
--Hossein 
--------------------------------------------------------------------------------------------------------------

Seyed H. HAERI (Hossein)

Research Assistant
Institute for Software Systems (STS)
Technical University of Hamburg (TUHH)
Hamburg, Germany

ACCU - Professionalism in programming - http://www.accu.org/
--------------------------------------------------------------------------------------------------------------

hossein_haeri
Joined: 2011-09-25,
User offline. Last seen 1 year 2 weeks ago.
Re: flatMap Confusion

Hi Josh,

> This is not the case.  You can't run a generator on something that is not a "collection-ish" i.e. you mean:
> for(x <- xs) yield f(x)  // A Map operation.
> *or*
> for {
>   x <- xs
>   y = f(x)
> } yield y   // Still a map.

Bingo! That's the difference: y = f(x) vs y <- f(x).

Thank a lot,
--Hossein

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

Seyed H. HAERI (Hossein)

Research Assistant
Institute for Software Systems (STS)
Technical University of Hamburg (TUHH)
Hamburg, Germany

ACCU - Professionalism in programming - http://www.accu.org/
--------------------------------------------------------------------------------------------------------------

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland