-
Notifications
You must be signed in to change notification settings - Fork 21
Match cases are not type constrained for simulated union type #5549
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Imported From: https://issues.scala-lang.org/browse/SI-5549?orig=1 |
@paulp said: class D[-A] (v: A) { }
def size(t: D[D[Int] with D[String]]) = t match {
case x: D[D[Int]] => 1
case x: D[D[String]] => 2
case x: D[D[Double]] => 3
case _ => 4
} That would be a reasonable thing to want, but you seem not to realize that it would not help you at all. The only case which will ever match there is the first one because of erasure. The compiler limits the parameters to D[D[Int]]s and D[D[String]]s, but you still won't be able to distinguish them by matching on their types. (You can distinguish them by matching on the value.) It doesn't bother trying to exclude D[D[Double]] because it can't tell one D[X] from another D[X] and it knows it. You're supposed to get unchecked warnings in a match like that - everyone ignores them, but at least I can say "if you'd read the unchecked warnings..." But actually it seems to be failing to warn with a parameterized type in the erasure zone, so I will open a ticket about that. |
@paulp said: |
Shelby Moore III (shelby) said (edited on Nov 7, 2012 3:46:52 PM UTC): The unchecked warning is appearing with my prior code, so no need to open a separate bug report. Thanks for catching the type hole that D[Any] was an allowable input to size. I fixed that below. scala> size(new D[Any](5 : Any))
error: type mismatch;
found : D[Any]
required: DD[D[Int] with D[String]]
size(new D[Any](5 : Any))
^ Also, I was able to eliminate the unchecked warnings as follows. scala> class D[-A] (v: A) {
def get = (v : Any)
}
defined class D
scala> class DD[-A >: D[Any]] (v: A) {
def get = (v : Any)
}
defined class DD
scala> implicit def neg[A](x: A) = new DD[D[A]]( new D[A](x) )
neg: [A](x: A)DD[D[A]]
scala> def size(t: DD[D[Int] with D[String]]) = t.get match { case x: D[_] =>
x.get match {
case x: Int => 1
case x: String => 2
case x: Double => 3
}
}
size: (t: DD[D[Int] with D[String]])Int Why can't the compiler reason that the Double case above is unreachable? Afaik, Scala will prevent any call of size with a D[D[Double]], but at the JVM such can't be prevented due to type erasure. But what if I don't care about interoption at the JVM level of linkage? I want to assume that all callers will respect my higher-level API, where size only inputs D[D[Int] with D[String]]. Is the current policy to make my desired assumption, or if not could there be a compiler flag to do so? |
Shelby Moore III (shelby) said (edited on Nov 7, 2012 3:47:15 PM UTC): scala> def text(t : D[Int]) = t match {
case x: D[Int] => 1
case x: D[String] => 2
}
error: unreachable code
case x: D[String] => 2
^ I realized why the compiler can't reason that the Double case is unreachable. There is no way to extract the parameter of D[Int] with D[String] from DD[-A], without losing the contravariance that gives the semantics of the union of Int and String. The extraction of the field v from DD and D is a two step process calling get twice, and afaics there is no way to express such in Scala to maintain the invariants of the combination (the type combining DD and D) across those two deconstruction steps. |
Shelby Moore III (shelby) said: |
Shelby Moore III (shelby) said: |
See bug #2 in the context of this mailing list post:
http://groups.google.com/group/shapeless-dev/browse_thread/thread/1f26830027f3517
"2. It doesn't exclude the
D[¬[Double]]
case from the match."The union type is important. Ceylon has it, and afaics it is necessary for supporting heterogeneous collections type-safely without resorting to the (probably unbearable for novices, and more "Scala is difficult to read" accusations) complexity of the experimental metascala.
P.S. There is a duplicate syntax-highlighted version buried nearer to the bottom of the following stackoverflow answer:
http://stackoverflow.com/questions/3508077/does-scala-have-type-disjunction-union-types/7460312#7460312
The text was updated successfully, but these errors were encountered: