Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala pattern match infers `Any` instead of an existential type, breaks type safety?

Tags:

types

scala

I ran into a puzzling type inference problem with case classes. Here's a minimal example:

trait T[X]
case class Thing[A, B, X](a: A, f: A => B) extends T[X]

def hmm[X](t: T[X]) = t match {
  case Thing(a, f) => f("this really shouldn't typecheck")
}

Scala decides that a: Any and f: Any => Any, but that's inappropriate; they really ought to have types a: SomeTypeA and f: SomeTypeA => SomeTypeB, where SomeTypeA and SomeTypeB are unknown types.

Another way of saying this is that I think the hypothetical Thing.unapply method should look something like

def unapply[X](t: T[X]): Option[(A, A => B)] forSome { type A; type B } = {
  t match {
    case thing: Thing[_, _, X] => Some((thing.a, thing.f))
  }
}

This version correctly gives a type error at f("this really shouldn't typecheck").

Does this seem like a bug in the compiler, or am I missing something?

Edit: This is on Scala 2.10.3.

like image 299
Alan O'Donnell Avatar asked Dec 03 '13 19:12

Alan O'Donnell


1 Answers

Mark Harrah pointed this out in the #scala channel on Freenode: yes, this is a bug.

https://issues.scala-lang.org/browse/SI-6680

like image 112
Kris Nuttycombe Avatar answered Sep 21 '22 04:09

Kris Nuttycombe