Closed
Description
Minimized code
infix abstract class TupleOf[T, +A]:
type Mapped[+A] <: Tuple
def map[B](x: T)(f: A => B): Mapped[B]
object TupleOf:
given TupleOf[EmptyTuple, Nothing] with
type Mapped[+A] = EmptyTuple
def map[B](x: EmptyTuple)(f: Nothing => B): Mapped[B] = x
given [A, Rest <: Tuple](using tup: Rest TupleOf A): TupleOf[A *: Rest, A] with
type Mapped[+A] = A *: tup.Mapped[A]
def map[B](x: A *: Rest)(f: A => B): Mapped[B] =
(f(x.head) *: tup.map(x.tail)(f))
def foo[T](xs: T)(using tup: T TupleOf Int): tup.Mapped[Int] = tup.map(xs)(_ + 1)
@main def test =
foo(EmptyTuple): EmptyTuple // ok
foo(1 *: EmptyTuple): Int *: EmptyTuple // nope
https://scastie.scala-lang.org/TQKBd1mmR6qygyuY0vMSMg
It works in Scala 2 : https://scastie.scala-lang.org/XTg2Thj5QYSyEzSNL5xUpQ
Output
Found: ?1.Mapped[Int]
Required: Int *: EmptyTuple
where: ?1 is an unknown value of type TupleOf.given_TupleOf_A_A[Int, EmptyTuple.type]
Expectation
Compiles. The Mapped
type of any TupleOf.given_TupleOf_A_A[Int, EmptyTuple.type]
value is [A] =>> A *: EmptyTuple
. So ?1.Mapped[Int]
should be reduced to Int *: EmptyTuple
.