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

Inference limitation when combining apply insertion and match type #21838

Open
smarter opened this issue Oct 23, 2024 · 0 comments
Open

Inference limitation when combining apply insertion and match type #21838

smarter opened this issue Oct 23, 2024 · 0 comments

Comments

@smarter
Copy link
Member

smarter commented Oct 23, 2024

Compiler version

ecc332f

Minimized code

  def m[T1 <: Tuple]: (Tuple.Head[T1] => Int) = ???

  def foo[T1 <: Tuple](h: Tuple.Head[T1]): Unit =
    val x: Int = m.apply(h) // ok
    val y: Int = m(h) // error

Output

69 |    val y: Int = m(h) // error
   |                   ^
   |               Found:    (h : Tuple.Head[T1])
   |               Required: Tuple.Head[Tuple]

Expectation

This should work, given that it works with an explicit apply or with an extra class involved:

  trait C[T1 <: Tuple] extends (Tuple.Head[T1] => Int)
  def m[T1 <: Tuple]: C[T1] = ???
  def foo[T1 <: Tuple](h: Tuple.Head[T1]): Unit =
    val x: Int = m.apply(h) // ok
    val y: Int = m(h) // ok

This comes up when trying to use givens to define conversions on match types (A =:= B inherits from A => B):

object Test:
  given ConcatMapIsMapConcat[
      T1 <: Tuple, T2 <: Tuple, F[_]
  ]: =:=[Tuple.Concat[Tuple.Map[T1, F], Tuple.Map[T2, F]], Tuple.Map[Tuple.Concat[T1, T2], F]] = ???

  def foo[T1 <: Tuple, T2 <: Tuple](t1: T1, t2: T2): Tuple.Map[Tuple.Concat[T1, T2], List] =
    val t1s: Tuple.Map[T1, List] = ???
    val t2s: Tuple.Map[T2, List] = ???

    t1s ++ t2s // error
    ConcatMapIsMapConcat(t1s ++ t2s) // error
    ConcatMapIsMapConcat.apply(t1s ++ t2s) // ok

The only workaround seems to be to use an implicit def:

object Test:
  implicit def ConcatMapIsMapConcat[
      T1 <: Tuple, T2 <: Tuple, F[_]]
  ](
      c: Tuple.Concat[Tuple.Map[T1, F], Tuple.Map[T2, F]]
  ): Tuple.Map[Tuple.Concat[T1, T2], F] = ???

  def foo[T1 <: Tuple, T2 <: Tuple](t1: T1, t2: T2): Tuple.Map[Tuple.Concat[T1, T2], List] =
    val t1s: Tuple.Map[T1, List] = ???
    val t2s: Tuple.Map[T2, List] = ???

    t1s ++ t2s // ok
    ConcatMapIsMapConcat(t1s ++ t2s) // ok
    ConcatMapIsMapConcat.apply(t1s ++ t2s) // ok
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

1 participant