Why can I write
val flat: List[Int] = List(Some(1), Some(2)).flatMap(i => i)
But not
val flat: List[Int] = List(Some(1), Some(2)).flatMap(_)
Why can I write
val flat: List[Int] = List(Some(1), Some(2)).flatMap(i => i)
But not
val flat: List[Int] = List(Some(1), Some(2)).flatMap(_)
The underscore is a placeholder for a variable. It's not, in and of itself, a function. flatMap
requires a function.
Also, in this case, there is a flatten
method which is defined on List
for which Option
has within the Predef
an implicit conversion such that what you've written can be condensed into just that call, List(Some(1)).flatten
By rules for underscore List(Some(1), Some(2)).flatMap(_)
is short for x => List(Some(1), Some(2)).flatMap(x)
, not List(Some(1), Some(2)).flatMap(x => x)
.
The short answer is the underscore can refer to an identity mapping, e.g. x => x
, but flatMap
requires a mapping to TraversableOnce[U]
such as a list of items.
For example, List(1, 2).flatMap(Seq(_))
works. List(1, 2).map(_ + 2)
also works. The first one is just identity mapping and the second one will return List(3, 4)
.
However, if you have complex transformation in the flatMap
of map
(more than one operator), you will have to write the lambda function properly, otherwise the compiler cannot correctly infer the type. See Scala unexpectedly not being able to ascertain type for expanded function.