Przekształcałem kod z 2,9 na 2,10 i natrafiłem na nieoczekiwany błąd kompilacji. Oto minimalna forma:Zachowanie flatMap zmieniono w 2.10.0
W pkt 2.9.2, to działa prawidłowo:
scala> List(1).flatMap(n => Set(1).collect { case w => w })
res0: List[Int] = List(1)
W 2.10.0, otrzymujemy błąd:
scala> List(1).flatMap(n => Set(1).collect { case w => w })
<console>:8: error: no type parameters for method flatMap: (f: Int => scala.collection.GenTraversableOnce[B])(implicit bf: scala.collection.generic.CanBuildFrom[List[Int],B,That])That exist so that it can be applied to arguments (Int => scala.collection.immutable.Set[_ <: Int])
--- because ---
argument expression's type is not compatible with formal parameter type;
found : Int => scala.collection.immutable.Set[_ <: Int]
required: Int => scala.collection.GenTraversableOnce[?B]
List(1).flatMap(n => Set(1).collect { case w => w })
^
<console>:8: error: type mismatch;
found : Int => scala.collection.immutable.Set[_ <: Int]
required: Int => scala.collection.GenTraversableOnce[B]
List(1).flatMap(n => Set(1).collect { case w => w })
^
<console>:8: error: Cannot construct a collection of type That with elements of type B based on a collection of type List[Int].
List(1).flatMap(n => Set(1).collect { case w => w })
^
Ale to działa dobrze w 2.10.0 jeśli wyraźnie włączyć wynik wewnętrzną w List
lub określenie rodzajowe typy flatmap
wyraźnie:
scala> List(1).flatMap(n => Set(1).collect { case w => w }.toList)
res1: List[Int] = List(1)
scala> List(1).flatMap[Int, List[Int]](n => Set(1).collect { case w => w })
res2: List[Int] = List(1)
Czy ktoś może mi wyjaśnić, co zmieniło się w wersji 2.10, co powoduje, że wnioskowanie o typie zawodzi tutaj, gdy nie było w 2,9?
EDIT:
Kopiąc głębiej, widzimy, że problem wynika z różnicy w zachowaniu collect
:
W 2.9.2:
scala> Set(1).collect { case w => w }
res1: scala.collection.immutable.Set[Int] = Set(1)
W 2.10.0:
scala> Set(1).collect { case w => w }
res4: scala.collection.immutable.Set[_ <: Int] = Set(1)
Prawdopodobnie powodem jest fakt, że Set
, w przeciwieństwie do, na przykład, List
, jest niezmiennikiem typu. Ale pełniejsze wyjaśnienie, a zwłaszcza takie, które daje motywację do tej zmiany, byłoby wspaniałe.
Czy to możliwe, aby zbiory kompatybilny dla nowej wartości dynamicznych ulepszania - czyli rzeczy, które „przedłużyć” Int zostanie przyjęta (zakładając, że mam właściwie zinterpretował poprawnie nowe pojęcie wartości dynamicznych. – chaotic3quilibrium