Reputation: 1727
I have a type X[D <: Int]
that I would like to convert to implicitly from a tuple.
Specifically a tuple of length D
whose members are all Int
should be convertable to an X[D]
.
I am not able to write a Conversion[A, B]
to properly perform this.
Scastie playground with my attempt
https://scastie.scala-lang.org/R3BEymtWSaqTCtDTsirTKw
import scala.language.implicitConversions
// tuple types
type TupleAllAre[A] = [T <: Tuple] =>> T =:= TupleElementsAre[T, A]
type TupleElementsAre[T <: Tuple, A] <: Tuple = T match
case A *: rest => A *: TupleElementsAre[rest, A]
case EmptyTuple => EmptyTuple
// tuple types work
val s1 = summon[TupleAllAre[Int][(Int, Int)]]
// Expected error
// val s2 = summon[TupleAllAre[Int][(Int, String, Int)]]
// target classes / methods
class X[D <: Int](x: Seq[Int]):
def size: Int = x.size
def definition[D <: Int](x: X[D]): Unit = ???
def def_with_conversion[T <: Tuple: TupleAllAre[Int]] (tuple: T) (using c: Conversion[T, X[Tuple.Size[T]]]): X[Tuple.Size[T]] = c(tuple)
class M[D <: Int]:
def apply(x: X[D]): Unit = ???
val m1 = M[2]()
extension [T <: Tuple: TupleAllAre[Int]] (tuple: T)
def ext(using c: Conversion[T, X[Tuple.Size[T]]]): X[Tuple.Size[T]] = c(tuple)
// conversion
given [T <: Tuple: TupleAllAre[Int]]: Conversion[T, X[Tuple.Size[T]]] = ???
// works with a non generic conversion
// given Conversion[(Int, Int), X[2]] = ???
// should all work
val x1: X[2] = (16, 16)
val d1 = definition[2](2, 2)
val d2: X[2] = def_with_conversion(2, 2)
val a1 = m1(2, 2)
val e1: X[2] = (2, 2).ext
Upvotes: 1
Views: 207
Reputation: 1118
If what you are trying to achieve is to have a type that X[D] that represent a tuple of D elements all Integer this is a way to achieve it:
import scala.compiletime.ops.int.*
type S = Singleton & Int
type X[D <: S] = D match
case 0 => EmptyTuple
case _ => Int *: X[-[D, 1]]
val x: X[2] = (1,2)
def definition[D <: S](x: X[D]): Unit = ()
val x1: X[2] = (16, 16)
println(x1)
val d1 = definition[2]((2, 2))
https://scastie.scala-lang.org/alfonsorr/pk2Avg4YToKaWtKUKxinJA
Upvotes: 2