7

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?

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
Mario Galic
  • 47,285
  • 6
  • 56
  • 98
  • It would certainly make more sense to infer `res1` to `List[Box[Shape]]` in this case, where they both extend a trait and you might want to add `Box[Rectangle]`, etc. later on – user May 31 '20 at 19:00
  • Not sure if this is the only problem, but `Box[Square] | Box[Circle]` is not a thing because of type erasure – simpadjo May 31 '20 at 19:15
  • @simpadjo Type erasure is irrelevant because type erasure occurs long after typechecking https://dotty.epfl.ch/docs/internals/overall-structure.html `Box[Square] with Box[Circle]` exists even in Scala 2. – Dmytro Mitin May 31 '20 at 20:51
  • @DmytroMitin but how is pattern-matching on `Box[Square] | Box[Circle]` possible at runtime? – simpadjo May 31 '20 at 20:59
  • 2
    @simpadjo You can [check](https://gist.github.com/DmytroMitin/257729dddd733527d4445903cd16047c) this with `scalacOptions += "-Xprint:genBCode"`. Basically it's matched with `Box[_]` at runtime. But once again this is irrelevant to type inference/typechecking. – Dmytro Mitin May 31 '20 at 22:25
  • 2
    @MarioGalic Quote from http://guillaume.martres.me/talks/dotty-tutorial/#/1/13 (slide 15 "Type inference and union types"): "By default, Dotty does not infer union types, they are approximated by a non-union supertype. Union types can be "too precise" and prevent legitimate code from compiling" – Dmytro Mitin Jun 04 '20 at 17:09
  • @MarioGalic although maybe this is outdated – Dmytro Mitin Jun 04 '20 at 17:12

0 Answers0