Scala - Почему нельзя вывести List of Seq для списка, содержащего Vector и List? - PullRequest
3 голосов
/ 14 сентября 2011

При попытке выполнить следующее в 2.8.1 / 2.9.0.1 REPL первый выдает ошибку.

val l = List(Vector(1,2), List(3,4,5))
error: type mismatch;
 found   : scala.collection.immutable.Vector[Int]
 required: scala.collection.immutable.Seq[Int]{def companion:     scala.collection.generic.GenericCompanion[scala.collection.immutable.Seq[Any]]; protected def thisCollection: Seq[Int]{def companion: scala.collection.generic.GenericCompanion[Seq[Any]]}; def dropRight(n: Int): scala.collection.immutable.Seq[Int]{def companion: scala.collection.generic.GenericCompanion[scala.collection.immutable.Seq[Any]]}; def takeRight(n: Int): scala.collection.immutable.Seq[Int]{def companion: scala.collection.generic.GenericCompanion[scala.collection.immutable.Seq[Any]]}; def slice(start: Int,end: Int): scala.collection.immutable.Seq[Int]{def companion: scala.collection.generic.GenericCompanion[scala.collection.immutable....
      val l = List(Vector(1,2), List(3,4,5))
                         ^
:5: error: type mismatch;
 found   : List[Int]
 required: scala.collection.immutable.Seq[Int]{def companion:     scala.collection.generic.GenericCompanion[scala.collection.immutable.Seq[Any]]; protected def thisCollection: Seq[Int]{def companion: scala.collection.generic.GenericCompanion[Seq[Any]]}; def dropRight(n: Int): scala.collection.immutable.Seq[Int]{def companion: scala.collection.generic.GenericCompanion[scala.collection.immutable.Seq[Any]]}; def takeRight(n: Int): scala.collection.immutable.Seq[Int]{def companion: scala.collection.generic.GenericCompanion[scala.collection.immutable.Seq[Any]]}; def slice(start: Int,end: Int): scala.collection.immutable.Seq[Int]{def companion: scala.collection.generic.GenericCompanion[scala.collection.immutable.Seq[Any]]}; def take(n: Int):...
       val l = List(Vector(1,2), List(3,4,5))
                                    ^

В то время как это успешно выполняется:

val l = List[Seq[Int]](Vector(1,2), List(3,4,5))
//evaluates fine to List[Seq[Int]] = List(Vector(1, 2), List(3, 4, 5))

Что такое тип scala пытаетсясделать вывод в первом случае?Это Seq со структурным типом?Почему он не может объединить Вектор и Список?Это какая-то недостающая особенность, или это так (требует явного определения типа), чтобы предотвратить выстрел в себя?

Ответы [ 2 ]

7 голосов
/ 14 сентября 2011

Это, очевидно, ошибка в модуле вывода типов, которая теперь была исправлена ​​ в scala 2.9.1 :

Welcome to Scala version 2.9.1.final (Java HotSpot(TM) Server VM, Java 1.6.0_18).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import collection.immutable._
import collection.immutable._

scala>  List(Vector(1, 2, 3), List(4, 5))
res0: List[scala.collection.immutable.Seq[Int]] = List(Vector(1, 2, 3), List(4, 5))
0 голосов
/ 14 сентября 2011

Исходя из ответа Даниэля здесь , Scala не использует вывод типа Хиндли-Милнера и вместо этого делает вывод локального типа, двигаясь слева направо.

В вашем первом объявлении первый списокmember Vector[Int], поэтому Scala говорит: «Хорошо, у меня есть List[Vector[Int]], но затем, когда он попадает во второй элемент списка, List[Int], он не может объединить это с Vector[Int]. Обобщения должны быть проблемой длялогический вывод, потому что списки, содержащие числа и строки , могут быть правильно определены как List[Any].

Что-то связанное: векторы и списки могут взаимодействовать в 2.9.0.1 через оператор ==.

scala> List[Int](1,2,3) == Vector[Int](1,2,3)
res2: Boolean = true

scala> List[Int](1,2,3) == Vector[Int](1,12,3)
res3: Boolean = false
...