在scala中,为什么list.flatMap(List)不起作用?

时间:2021-04-17 07:21:07

This works well

这很好用

val l = List(1,2,3)
l.flatMap(x => List(x))

But this doesn't work:

但这不起作用:

l.flatMap(List)

And this doesn't work either:

这也不起作用:

l.flatmap(List.apply _)

Does anyone have ideas about this? Thanks!

有没有人有这个想法?谢谢!

2 个解决方案

#1


For List[A], flatMap expects a function from A => GenTraversableOnce[B]. The problem with using List.apply in that particular syntax is that apply allows repeated parameters A*, which is syntactic sugar for Seq[A]. So List.apply is really a Seq[A] => List[A], which is not the same as A => List[A]. And we can see that in the error message:

对于List [A],flatMap期望A => GenTraversableOnce [B]中的函数。在该特定语法中使用List.apply的问题是apply允许重复参数A *,这是Seq [A]的语法糖。所以List.apply实际上是Seq [A] => List [A],它与A => List [A]不同。我们可以在错误消息中看到:

scala> l.flatMap(List.apply)
<console>:9: error: polymorphic expression cannot be instantiated to expected type;
 found   : [A]Seq[A] => List[A]
 required: Int => scala.collection.GenTraversableOnce[?]
              l.flatMap(List.apply)

What you can do is make it clear that you are only using one parameter:

您可以做的是明确表示您只使用一个参数:

scala> l.flatMap(List(_))
res5: List[Int] = List(1, 2, 3)

scala> l.flatMap(List.apply(_))
res6: List[Int] = List(1, 2, 3)

And l.flatMap(List) could never work, because List is a class, and Scala will not treat it with the apply sugar to produce l.flatMap(List.apply).

并且l.flatMap(List)永远不会工作,因为List是一个类,而Scala不会使用apply sugar来处理它来生成l.flatMap(List.apply)。

#2


This is because List.apply uses varargs:

这是因为List.apply使用varargs:

def apply[A](xs: A*): List[A]

You are looking for a method that turns a single item into a list containing only that item. There is no special method just for that on the List object. Instead, they provide a more general method that takes any number of arguments, allowing your first statement (List(1, 2, 3)) to work.

您正在寻找一种方法,将单个项目转换为仅包含该项目的列表。 List对象上没有特殊的方法。相反,它们提供了一个更通用的方法,它接受任意数量的参数,允许你的第一个语句(List(1,2,3))工作。

You need to provide parentheses to create a List of only one object, thus you need to do the same when referring to the apply method using a _ wildcard:

您需要提供括号来创建只有一个对象的List,因此在使用_通配符引用apply方法时需要执行相同的操作:

val listOfOne = List(1)

l.flatMap(List(_))
l.flatMap(List.apply(_))

#1


For List[A], flatMap expects a function from A => GenTraversableOnce[B]. The problem with using List.apply in that particular syntax is that apply allows repeated parameters A*, which is syntactic sugar for Seq[A]. So List.apply is really a Seq[A] => List[A], which is not the same as A => List[A]. And we can see that in the error message:

对于List [A],flatMap期望A => GenTraversableOnce [B]中的函数。在该特定语法中使用List.apply的问题是apply允许重复参数A *,这是Seq [A]的语法糖。所以List.apply实际上是Seq [A] => List [A],它与A => List [A]不同。我们可以在错误消息中看到:

scala> l.flatMap(List.apply)
<console>:9: error: polymorphic expression cannot be instantiated to expected type;
 found   : [A]Seq[A] => List[A]
 required: Int => scala.collection.GenTraversableOnce[?]
              l.flatMap(List.apply)

What you can do is make it clear that you are only using one parameter:

您可以做的是明确表示您只使用一个参数:

scala> l.flatMap(List(_))
res5: List[Int] = List(1, 2, 3)

scala> l.flatMap(List.apply(_))
res6: List[Int] = List(1, 2, 3)

And l.flatMap(List) could never work, because List is a class, and Scala will not treat it with the apply sugar to produce l.flatMap(List.apply).

并且l.flatMap(List)永远不会工作,因为List是一个类,而Scala不会使用apply sugar来处理它来生成l.flatMap(List.apply)。

#2


This is because List.apply uses varargs:

这是因为List.apply使用varargs:

def apply[A](xs: A*): List[A]

You are looking for a method that turns a single item into a list containing only that item. There is no special method just for that on the List object. Instead, they provide a more general method that takes any number of arguments, allowing your first statement (List(1, 2, 3)) to work.

您正在寻找一种方法,将单个项目转换为仅包含该项目的列表。 List对象上没有特殊的方法。相反,它们提供了一个更通用的方法,它接受任意数量的参数,允许你的第一个语句(List(1,2,3))工作。

You need to provide parentheses to create a List of only one object, thus you need to do the same when referring to the apply method using a _ wildcard:

您需要提供括号来创建只有一个对象的List,因此在使用_通配符引用apply方法时需要执行相同的操作:

val listOfOne = List(1)

l.flatMap(List(_))
l.flatMap(List.apply(_))