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

No kind inference for match types #10077

Closed
IndiscriminateCoding opened this issue Oct 23, 2020 · 4 comments
Closed

No kind inference for match types #10077

IndiscriminateCoding opened this issue Oct 23, 2020 · 4 comments

Comments

@IndiscriminateCoding
Copy link

IndiscriminateCoding commented Oct 23, 2020

Minimized code

trait T[F[_[_]]]
object T:
  type Inner[x] = x match { case T[f] => f }

trait Monad[F[_]]
type TMonad = T[Monad]

trait U[T0]:
  def f(x: T.Inner[T0]): Unit

class X extends U[T[Monad]]:
  /* it is impossible to give valid type for f */
  def f(x: T.Inner[T[Monad]]): Unit // Missing type parameter for Monad

Output

Missing type parameter for Monad

Expectation

I'm trying to use match types as a replacement for scala2 type projections, and it seems that it is not always possible now.
So I expect that it would be possible to define abstract method f as follows:

def f(x: T.Inner[T0][List]): Unit
@OlivierBlanvillain
Copy link
Contributor

OlivierBlanvillain commented Oct 26, 2020

Maybe I'm misunderstanding your example, but I think the compiler is doing its job properly here. Indeed, your definition of f in the minimized code has a parameter x with a HKT, which shouldn't compile. Here is a further minimized example without match type:

scala> trait Foo {
     |   type X
     |   def f(x: X) = ()
     | }
     | 
     | class Bar extends Foo {
     |   type X = List
     |   def f(x: List) = ()
     | }
8 |  def f(x: List) = ()
  |           ^^^^
  |           Missing type parameter for List

@IndiscriminateCoding
Copy link
Author

@OlivierBlanvillain the issue is, it is not possible to declare f with a type that would be properly reduced later:

def f(x: T.Inner[T0][List]): Unit // won't compile

It seems that match types are purely syntactical (i.e. no kind infered for match type declaration), which leads to this weird situation

@OlivierBlanvillain
Copy link
Contributor

I see, makes sense, you essentially want something like the following:

trait T[F[_[_]]]                                                                           
object T:
  type Inner[x, y[_]] = x match { case T[f] => f[y] }

trait U[T0]:
  def f(x: T.Inner[T0, List]): Unit

It looks like in your original example, the compiler thinks that f in case T[f] is a ground type, which is incorrect. I will try to look into it.

@OlivierBlanvillain OlivierBlanvillain self-assigned this Oct 26, 2020
@OlivierBlanvillain
Copy link
Contributor

How about:?

trait T[F[_[_]]]

type Inner[x] = [X[_]] =>> x match { case T[f] => f[X] }

trait Monad[F[_]]
type TMonad = T[Monad]

trait U[T0]:
  type T0_member = T0
  def f(x: Inner[T0][List]): Unit

class X extends U[T[Monad]]:
  def f(x: Inner[T0_member][List]): Unit = ???

@odersky odersky closed this as completed in a902b75 Aug 6, 2021
odersky added a commit that referenced this issue Aug 6, 2021
tanishiking pushed a commit to tanishiking/scala3 that referenced this issue Aug 10, 2021
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