Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected Trait Behavior

Tags:

scala

traits

Given a simple Algebraic Data Type of Parent:

scala> sealed trait Parent
defined trait Parent

scala> case object Boy extends Parent
defined object Boy

scala> case object Girl extends Parent
defined object Girl

I defined a trait:

scala> trait HasGirl { 
     |   val x: Girl.type
     | }
defined trait HasGirl

Then, I created a case class that implemented HasGirl, but provided an x value of Boy.type.

scala> case class Thing(x: Boy.type) extends HasGirl
defined class Thing

I had expected a compile-time error, since I don't see how an x of type Boy.type conforms to val x: Girl.type.

What's going on here?

like image 820
Kevin Meredith Avatar asked Nov 28 '15 17:11

Kevin Meredith


1 Answers

It seems that singleton types without members are type-equivalent somehow here. Perhaps it's a bug (you filed a ticket). For example, the following produces a runtime-error:

sealed trait Parent
case object Boy  extends Parent
case object Girl extends Parent

trait HasGirl {
  val x: Girl.type
}

case class Thing(x: Boy.type) extends HasGirl {
  def y: Girl.type = (this: HasGirl).x
}


val t = Thing(Boy)
t.y   // ClassCastException !

If I add a member, you get a compile-time error:

sealed trait Parent
case object Boy  extends Parent
case object Girl extends Parent { def hello = 1234 }

trait HasGirl {
  val x: Girl.type
}

case class Thing(x: Boy.type) extends HasGirl
<console>:57: error: overriding value x in trait HasGirl of type Girl.type;
 value x has incompatible type
       case class Thing(x: Boy.type) extends HasGirl
                        ^
like image 145
0__ Avatar answered Sep 27 '22 09:09

0__