Skip to content

Instantly share code, notes, and snippets.

@mjhopkins
Last active February 7, 2017 03:21
Show Gist options
  • Save mjhopkins/282f9971a98c2dcdad70a1dd3b5bcb57 to your computer and use it in GitHub Desktop.
Save mjhopkins/282f9971a98c2dcdad70a1dd3b5bcb57 to your computer and use it in GitHub Desktop.
Demonstrates a scenario where Scala fails to refine a type
sealed trait Role[N <: Entity]
case object VIP extends Role[Customer]
case object Shopper extends Role[Customer]
case object Manager extends Role[Staff]
case object Employee extends Role[Staff]
sealed trait Entity
case class Customer(name: String) extends Entity
case class Staff(id: Int) extends Entity
sealed trait RolePair {
type N <: Entity
val role: Role[N]
val entity: N
}
object RolePair {
def apply[M <: Entity](r: Role[M], n: M): RolePair = new RolePair {
type N = M
val role: Role[N] = r
val entity: N = n
}
def unapply(rp: RolePair): Some[(Role[rp.N], rp.N)] = Some((rp.role, rp.entity))
// Scala 2 version (broken in 2.11, 2.12)
// def unapply(rp: RolePair): Some[(Role[N], N)] forSome { type N <: Entity } = Some((rp.role, rp.entity))
}
object RolePairTest {
def main(args: Array[String]): Unit = {
val roles: List[RolePair] = List(
RolePair(Manager, Staff(1)),
RolePair(Shopper, Customer("Max")),
RolePair(Employee, Staff(2)),
RolePair(Employee, Staff(3)),
RolePair(VIP, Customer("Lucy"))
)
// The following hould be a List[Customer], but it is only a List[RolePair#N] under dotty (List[Entity] under 2.11, 2.12)
// This worked in 2.10 but is broken in 2.11 and dotty
val vips =
roles collect {
case RolePair(VIP, customer) => customer
}
vips foreach { vip => println(vip.name) }
val vipsAndManagers = // Should be a List[Customer | Manager], but it is only a List[RolePair#N]
roles collect {
case RolePair(VIP, customer) => customer
case RolePair(Manager, manager) => manager
}
}
}
@mjhopkins
Copy link
Author

Note that I can't even call .name within the body of the case statement on line 47.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment