-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Another GADT typechecking error #13074
Comments
I don't think there is any logic in place to deal with constraints of the form Workaround: def unbox2[X, Y](box: Box[X * Y]): (X * Y) = unbox2Aux(box)
def unbox2Aux[A](box: Box[A]): A =
box match
case Box2x2(v) => v |
That's right, but:
This is a problem with minimized examples: workaround might exist and not even look too bad, while on a realistic example, workarounds, if they exist at all, have a tremendous cost. |
I did not say the example needs injectivity. I just remarked that injectivity cannot be assumed here. If it could (for example, through an annotation), the problem would go away, and injectivity is something some people may be expecting, since it's the default in languages like Haskell. Another workaround, as usual, is to encode all equational reasoning in lower- and upper- bounded abstract type members, and use explicit type ascriptions. It's also not ideal, but at least it's more explicit in advanced cases like this. |
#fixed-in-scala2 😛
|
Perhaps the two of you are already well aware, but in case it's useful, here's the explanation it gives:
|
👍 Passing some evidence of injectivity of an abstract type would be much wanted, especially for cases where injectivity is actually essential.
Don't know about that. My usual workaround for non-working pattern matching is to give up pattern matching and do OO-style multiple dispatch through nested virtual method calls on the involved objects. Some of those methods need to take an explicit |
To be clear, here is what I propose (it compiles): abstract class Eq[A, B]:
type Up >: A <: B
type Down >: B <: A
class Module[*[_, _]] {
sealed trait Box[A]:
type BoxA = A
case class Box2x2[A, B, C, D](value: (A * B) * (C * D)) extends Box[(A * B) * (C * D)]:
val ev: Eq[BoxA, (A * B) * (C * D)] = new{}
def unbox2[X, Y](box: Box[X * Y]): (X * Y) =
box match
case b @ Box2x2(v) => v: b.ev.Down
} |
Could this approach be used to derive |
Yes, though you actually need to phrase it in a way that's a bit of more general: abstract class Eq[A, B]:
type Ev >: B | A <: A & B
def toEqF[A, B, F[_]](eq: Eq[A, B]): Eq[F[A], F[B]] =
new Eq[F[eq.Ev], F[eq.Ev]]{} (This |
Compiler version
3.0.2-RC1
Minimized code
Output
Expectation
The code should typecheck, as per the explanation in the code comment.
The text was updated successfully, but these errors were encountered: