我有一个类型X[D <: Int]
,我想从元组隐式转换为它。具体地,其成员均为Int
的长度为D
的元组应当可转换为X[D]
。
我无法编写Conversion[A, B]
来正确执行此操作。
Scastie游乐场与我的尝试
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
如果你想要实现的是一个X[D]类型,它表示D元素的元组all Integer,这是实现它的一种方法:
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