List of shapes infers to List[Shape]
but list of boxed shapes infers to List[Box[Square | Circle]]
scala> sealed trait Shape
| case class Square() extends Shape
| case class Circle() extends Shape
| case class Box[+T <: Shape](t: T)
| List(Square(), Circle())
| List(Box(Square()), Box(Circle()))
val res0: List[Shape & Product & Serializable] = List(Square(), Circle())
val res1: List[Box[Square | Circle]] = List(Box(Square()), Box(Circle()))
Why is res0
not typed to List[Square | Circle]
in symmetry with List[Box[Square | Circle]]
, or vice-versa?
Dotty defines least upper bound in terms of union types
the least upper bound (lub) of a set of types is the union of these types. This replaces the definition of least upper bound in the Scala 2 specification.
What are the rules now for unification relative to this change?
res1
toList[Box[Shape]]
in this case, where they both extend a trait and you might want to addBox[Rectangle]
, etc. later on – GherardoBox[Square] | Box[Circle]
is not a thing because of type erasure – GiorgioBox[Square] with Box[Circle]
exists even in Scala 2. – FraydaBox[Square] | Box[Circle]
possible at runtime? – GiorgioscalacOptions += "-Xprint:genBCode"
. Basically it's matched withBox[_]
at runtime. But once again this is irrelevant to type inference/typechecking. – Frayda