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

Implement parameter dependent case classes #8073

Open
odersky opened this issue Jan 22, 2020 · 0 comments · May be fixed by #21698
Open

Implement parameter dependent case classes #8073

odersky opened this issue Jan 22, 2020 · 0 comments · May be fixed by #21698

Comments

@odersky
Copy link
Contributor

odersky commented Jan 22, 2020

minimized example

From #8069:

trait A:
  type B

enum Test:
  case Test(a: A, b: a.B)   // error: Implementation restriction: case classes cannot have dependencies between parameters

case class Test2(a: A, b: a.B) // error: Implementation restriction: case classes cannot have dependencies 

It would be great if we could lift the implementation restriction and admit case classes (and enum cases) with parameter dependencies.

To get there, we need a systematic study where we have to do the right substitutions.

One immediate problem, which caused #8069 is that fromProduct does not work as given since it
casts to unsubstituted parameter types. E.g. for class Test2, fromProduct would contain code like this:

new C(
  x.productElement(0).asInstanceOf[A],
  x.productElement(1).asInstanceOf[a.B])

where the a in a.B is unbound.

I suspect there will also be other problems with pattern matching, and maybe elsewhere. So it will require a focussed effort to get there. But the benefits (dependent ADTs) would be potentially very significant!

odersky added a commit to dotty-staging/dotty that referenced this issue Jan 22, 2020
This avoids the crash but intorduces an implementation restriction. I have opened
scala#8073, which suggests a full implementation of parameter dependent case classes
so that the restriction can be dropped.
odersky added a commit to dotty-staging/dotty that referenced this issue Jan 22, 2020
This avoids the crash but intorduces an implementation restriction. I have opened
scala#8073, which suggests a full implementation of parameter dependent case classes
so that the restriction can be dropped.
smarter added a commit to dotty-staging/dotty that referenced this issue Oct 3, 2024
This lets us write:

    trait A:
      type B

    case class CC(a: A, b: a.B)

Pattern matching works but isn't dependent yet:

    x match
      case CC(a, b) =>
        val a1: A = a
        // Dependent pattern matching is not currently supported
        // val b1: a1.B = b
        val b1 = b // Type is CC#a.B

(for my usecase this isn't a problem, I'm working on a type constraint API
which lets me write things like `case class CC(a: Int, b: Int
GreaterThan[a.type])`)

Because case class pattern matching relies on the product selectors `_N`, making
it dependent is a bit tricky, currently we generate:

    case class CC(a: A, b: a.B):
      def _1: A = a
      def _2: a.B = b

So the type of `_2` is not obviously related to the type of `_1`, we probably
need to change what we generate into:

    case class CC(a: A, b: a.B):
      @uncheckedStable def _1: a.type = a
      def _2: _1.B = b

But this can be done in a separate PR.

Fixes scala#8073.
@smarter smarter linked a pull request Oct 3, 2024 that will close this issue
smarter added a commit to dotty-staging/dotty that referenced this issue Oct 3, 2024
This lets us write:

    trait A:
      type B

    case class CC(a: A, b: a.B)

Pattern matching works but isn't dependent yet:

    x match
      case CC(a, b) =>
        val a1: A = a
        // Dependent pattern matching is not currently supported
        // val b1: a1.B = b
        val b1 = b // Type is CC#a.B

(for my usecase this isn't a problem, I'm working on a type constraint API
which lets me write things like `case class CC(a: Int, b: Int
GreaterThan[a.type])`)

Because case class pattern matching relies on the product selectors `_N`, making
it dependent is a bit tricky, currently we generate:

    case class CC(a: A, b: a.B):
      def _1: A = a
      def _2: a.B = b

So the type of `_2` is not obviously related to the type of `_1`, we probably
need to change what we generate into:

    case class CC(a: A, b: a.B):
      @uncheckedStable def _1: a.type = a
      def _2: _1.B = b

But this can be done in a separate PR.

Fixes scala#8073.
smarter added a commit to dotty-staging/dotty that referenced this issue Oct 3, 2024
This lets us write:

    trait A:
      type B

    case class CC(a: A, b: a.B)

Pattern matching works but isn't dependent yet:

    x match
      case CC(a, b) =>
        val a1: A = a
        // Dependent pattern matching is not currently supported
        // val b1: a1.B = b
        val b1 = b // Type is CC#a.B

(for my usecase this isn't a problem, I'm working on a type constraint API
which lets me write things like `case class CC(a: Int, b: Int
GreaterThan[a.type])`)

Because case class pattern matching relies on the product selectors `_N`, making
it dependent is a bit tricky, currently we generate:

    case class CC(a: A, b: a.B):
      def _1: A = a
      def _2: a.B = b

So the type of `_2` is not obviously related to the type of `_1`, we probably
need to change what we generate into:

    case class CC(a: A, b: a.B):
      @uncheckedStable def _1: a.type = a
      def _2: _1.B = b

But this can be done in a separate PR.

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

Successfully merging a pull request may close this issue.

2 participants