To understand how this is working, it can be useful to explicitly unpack the functions you're sending to map
and flatMap
and examine their signatures. I've rewritten them here, so you can see that f
is a function mapping from Int
to an (Int, Int)
tuple, and g
is a function that maps from Int
to a List[Int]
.
val f: (Int) => (Int, Int) = x => (x*2, x*3)
val g: (Int) => List[Int] = x => List(x*2, x*3)
List(1,2,3).map(f)
//res0: List[(Int, Int)] = List((2,3), (4,6), (6,9))
List(1,2,3).map(g)
//res1: List[List[Int]] = List(List(2, 3), List(4, 6), List(6, 9))
//List(1,2,3).flatMap(f) // This won't compile
List(1,2,3).flatMap(g)
//res2: List[Int] = List(2, 3, 4, 6, 6, 9)
So why won't flatMap(f)
compile? Let's look at the signature for flatMap
, in this case pulled from the List
implementation:
final override def flatMap[B, That](f : scala.Function1[A, scala.collection.GenTraversableOnce[B]])(...)
This is a little difficult to unpack, and I've elided some of it, but the key is the GenTraversableOnce
type. List
, if you follow it's chain of inheritance up, has this as a trait it is built with, and thus a function that maps from some type A
to a List
(or any object with the GenTraversableOnce
trait) will be a valid function. Notably, tuples do not have this trait.
That is the in-the-weeds explanation why the typing is wrong, and is worth explaining because any error that says 'cannot resolve reference with such a signature' means that it can't find a function that takes the explicit type you're offering. Types are very often inferred in Scala, and so you're well-served to make sure that the type you're giving is the type expected by the method you're calling.
Note that flatMap
has a standard meaning in functional programming, which is, roughly speaking, any mapping function that consumes a single element and produces n elements, but your final result is the concatenation of all of those lists. Therefore, the function you pass to flatMap
will always expect to produce a list, and no flatMap
function would be expected to know how to act on single elements.