在Scala中,为什么我要得到“多态表达式不能实例化为预期类型”?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (39)

为什么Scala2.9.0.1中会出现以下情况?

scala> def f(xs: Seq[Either[Int,String]]) = 0
f: (xs: Seq[Either[Int,String]])Int

scala> val xs = List(Left(0), Right("a")).iterator.toArray
xs: Array[Product with Serializable with Either[Int,java.lang.String]] = Array(Left(0), Right(a))

scala> f(xs)
res39: Int = 0

scala> f(List(Left(0), Right("a")).iterator.toArray)
<console>:9: error: polymorphic expression cannot be instantiated to expected type;
 found   : [B >: Product with Serializable with Either[Int,java.lang.String]]Array[B]
 required: Seq[Either[Int,String]]
       f(List(Left(0), Right("a")).iterator.toArray)
                                            ^

一个更好的例子(不能100%肯定这表明了同样的潜在现象):

Seq(0).toArray : Seq[Int] // compiles
Seq(Some(0)).toArray : Seq[Option[Int]] // doesn't
提问于
用户回答回答于

如果你手动将其转换为可用Seq

scala> f(xs.toSeq)
res4: Int = 0

Scala Array不是Seq(因为它实际上是一个Java数组)。但是一个WappedArray是。你也可以重新定义你的功能f

scala> def f[A <% Seq[Either[Int,String]]](xs: A) = 0
f: [A](xs: A)(implicit evidence$1: (A) => Seq[Either[Int,String]])Int

scala> f(xs)
res5: Int = 0

顺便说一句,在调用之前不需要获取迭代器toArray

用户回答回答于

无论如何,问题是List(Left(0), Right("a")).iterator.toArray无法在预期的边界内推断出这种类型f。它不符合Seq[Either[Int, String]]没有隐式转换的情况,也不能应用隐式转换,因为它(类型)无法确定。这就像一个鸡蛋和鸡的问题。

如果使用<%或将其分配给val,则会在推理中打破循环。

扫码关注云+社区