Why can I not flatMap a List[Option] using undersc

2020-02-14 06:57发布

问题:

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(_)

回答1:

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



回答2:

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).



回答3:

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.



标签: scala