Reputation: 2100
what is the difference between map and flatMap? As in we can do a
1 to 5 map(c => println(c))
but not
1 to 5 flatMap(c => println(c))
On the other hand, this works
def h(i: Int) = if (i >= 2) Some(i) else None
1 to 5 flatMap(h)
I understand that flatMap is map and flatten, but not sure when a map can be used and when a flatMap can be used.
Upvotes: 2
Views: 4026
Reputation: 30276
The error is:
Type mismatch, expected: (int) => GenTraverableOnce[NotInferedB], actual: (int) => Unit
Because flatMap
is a combination of map
and flatten
. So flatMap
will runs map on every element of sequence, and then run flatten.
For example: [1,2][2,3]
--> [1,2,2,3]
Scala cannot do that with type Unit. Technically because Unit doesn't implement GenTraverableOnce
. Option
doesn't either, but Option[A]
can be implicit converted to Iterable[A]
, which is GenTraverableOnce[A]
. Here is the reference
Upvotes: 1
Reputation: 12090
Let's see the signature of flatMap.
def flatMap[B](f: (Int) ⇒ GenTraversableOnce[B]): TraversableOnce[B]
and the signature of map
def map[B](f: (A) ⇒ B): IndexedSeq[B]
You can see that the result type of f
must be GenTraversableOnce[B]
for flatMap
.
but there's no restriction in the result type of f
for map
.
The result type of println(x)
is Unit
and result type of x+2
is Int
. Since both does not implement GenTraversableOnce[B]
, you cannot do flatMap(x=>println(x))
nor flatMap(x=>x+2)
.
On the other hand Some(i)
and None
have type of Option[Int]
, which can be implicitly converted to Iterable[Int]
source
The signature of Iterable is
trait Iterable[+A] extends Traversable[A]
and Traversable is
trait Traversable[+A] .. with TraversableOnce[A]`
and finally TraversableOnce is
trait TraversableOnce[+A] extends GenTraversableOnce[A]
hence Option[Int]
implements GenTraversableOnce[Int]
so you can use it as result of flatMap[Int]
Upvotes: 10