Srinivas
Srinivas

Reputation: 2100

difference between map and flatMap in scala

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

Answers (2)

hqt
hqt

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

ymonad
ymonad

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

Related Questions