1

Using the sbt dotty plugin:

addSbtPlugin("com.felixmulder" % "sbt-dotty" % "0.1.9")

And running sbt console, I try out the new union type feature:

Starting dotty interpreter...
Welcome to Scala.next (pre-alpha, git-hash: 606e36b)  (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_112).
Type in expressions to have them evaluated.
Type :help for more information.
scala> case class A(val x: Int, y: Double) 
defined class A
scala> case class B(val x: Int, y: String) 
defined class B
scala> def getX(o: A | B): Int = o.x 
-- [E008] Member Not Found Error: <console> ------------------------------------
8 |def getX(o: A | B): Int = o.x
  |                          ^^^
  |                          value `x` is not a member of (A | B)(o)

Why doesn't this work? Am I using union types wrong? Is this just not working yet?

clay
  • 18,138
  • 28
  • 107
  • 192

1 Answers1

1

I don't think that's supposed to actually work. It does work if A and B extend a common interface that asserts they each have an x: Int:

trait C { def x: Int }

case class A(x: Int, y: Double) extends C

case class B(x: Int, y: String) extends C

def getX(o: A | B): Int = o.x

scala> getX(A(1, 2)) 
val res0: Int = 1

Without it, the compiler would need to reflectively look at A and B to determine if they had the same x defined, which doesn't seem in line with the goal of simplifying Scala's type system.

Of course, the supporting documentation is pretty much non-existent with no complete specification at this point. I think perhaps this slide is a source of confusion, as it isn't compilable code.

Michael Zajac
  • 55,144
  • 7
  • 113
  • 138
  • That DarkDimius slide was the source of my confusion. Thank you. – clay Mar 08 '17 at 14:57
  • If A and B must common interface, then we are using inheritance. How is union type better than this or help in this case? – thlim Apr 12 '18 at 05:42
  • @thlim Because the union type is used as proof that `o` is an `A` or `B`. Union types on their own say nothing about how `A` and `B` are related, because they don't have to be. – Michael Zajac Apr 14 '18 at 01:00