Open
Description
Compiler version
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