Skip to content
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

Generalize unapply pattern matching #9843

Open
odersky opened this issue Sep 21, 2020 · 0 comments
Open

Generalize unapply pattern matching #9843

odersky opened this issue Sep 21, 2020 · 0 comments

Comments

@odersky
Copy link
Contributor

odersky commented Sep 21, 2020

We need an answer for the question:

What is a legal prefix pre for a pattern of the form

  p(x1, ..., xN)

and what does it translate to? The immediate use case is if p ends in type arguments. E.g.

  p[T](x1, ..., xN)

The Status Quo

Dotty typechecks this pattern if p is a parameterized class (see #9840). We have the following code:

object Typeable:
  class instanceOf[T: Typeable]:
    def unapply(x: Any): Option[T] = ...

x match
    case Typeable.instanceOf[T](x) => ...

The pattern match translates to new Typeable.instanceOf[T].unapply(x). It also works if instanceOf is a function that returns a class instance containing the unapply method. In each case, the type parameter goes with the method and/or class, not with the unapply. Is that the right convention? I tried to do similar things with Scala2. The parser does accept type arguments in constructor patterns but I was unable to get anything to typecheck.

Possible Variant 1:

Generalize the current behavior to say p can be any idempotent expression that has an unapply method. This would enable a lot more use cases. But it would be a significant complication for the parser. The parser now has to be prepared to parse either a pattern or an expression.

Possible Variant 2:

If p is of the form q[T1, ..., Tn], make [T1, ...., Tn] arguments to the unapply method which must now exist as a member of q. If I understand the comment in shapeless Typeable,
this is what TypeLevel Scala 4 did. This would be incompatible with Dotty's current behavior, however.

Possible Variant 3:

Adopt (1) and (2), but require every more general expression to be in {....}. E.g.

 case {Typeable.instanceOf[T]}(x) => ...

would translate the same way as (1), whereas

 case Typeable.instanceOf[T](x) => ...

would translate the same way as (2). This would not cause new parsing problems, and would make it clearer where the unapply is. The price to pay is more complicated syntax and possible choice paralysis.

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

No branches or pull requests

2 participants