2
Warum wird der Scala-Compiler Sie nicht flatMap
eine Set[Set[_ <: SomeType]]
lassen, aber lassen Sie flatMap
eine Seq[Seq[_ <: SomeType]]
? Dieses Verhalten wird im folgenden Scala-REPL-Protokoll demonstriert.Warum können Sie ein Set nicht flatMap, wenn die Elemente nicht markiert sind, aber Sie können ein Seq FlatMap?
scala> class A
defined class A
scala> case class B extends A
defined class B
// If inner collection is of type Set[B] it works
scala> val x = Set(Set(B(), B()), Set(B(), B()))
x: scala.collection.immutable.Set[scala.collection.immutable.Set[B]] = Set(Set([email protected], [email protected]), Set([email protected], [email protected]))
scala> x flatMap { el => el }
res8: scala.collection.immutable.Set[B] = Set([email protected], [email protected], [email protected], [email protected])
// If inner collection of type Set[_ <: A] it doesn't work
scala> val x: Set[Set[_ <: A]] = Set(Set(B(), B()), Set(B(), B()))
x: Set[Set[_ <: A]] = Set(Set([email protected], [email protected]), Set([email protected], [email protected]))
scala> x flatMap { el => el }
<console>:15: error: no type parameters for method flatMap: (f: Set[_ <: A] => scala.collection.GenTraversableOnce[B])(implicit bf: scala.collection.generic.CanBuildFrom[scala.collection.immutable.Set[Set[_ <: A]],B,That])That exist so that it can be applied to arguments (Set[_ <: A] => scala.collection.immutable.Set[_ <: A])
--- because ---
argument expression's type is not compatible with formal parameter type;
found : Set[_ <: A] => scala.collection.immutable.Set[_ <: A]
required: Set[_ <: A] => scala.collection.GenTraversableOnce[?B]
x flatMap { el => el }
^
<console>:15: error: type mismatch;
found : Set[_ <: A] => scala.collection.immutable.Set[_ <: A]
required: Set[_ <: A] => scala.collection.GenTraversableOnce[B]
x flatMap { el => el }
^
// Try the same with Seq
scala> val x = Seq(Seq(B(), B()), Seq(B(), B()))
x: Seq[Seq[B]] = List(List([email protected], [email protected]), List([email protected], [email protected]))
// Works with inner of Seq[B]
scala> x flatMap { el => el }
res10: Seq[B] = List([email protected], [email protected], [email protected], [email protected])
scala> val x: Seq[Seq[_ <: A]] = Seq(Seq(B(), B()), Seq(B(), B()))
x: Seq[Seq[_ <: A]] = List(List([email protected], [email protected]), List([email protected], [email protected]))
// Works with inner of Seq[_ <: A]
scala> x flatMap { el => el }
res11: Seq[A] = List([email protected], [email protected], [email protected], [email protected])
// If inner collection of type Set[_ <: A] it works if we convert to Seq and back to Set again
scala> val x: Set[Set[_ <: A]] = Set(Set(B(), B()), Set(B(), B()))
x: Set[Set[_ <: A]] = Set(Set([email protected], [email protected]), Set([email protected], [email protected]))
scala> x.toSeq flatMap { elem => elem.toSeq } toSet
res16: scala.collection.immutable.Set[A] = Set([email protected], [email protected], [email protected], [email protected])