I would like to have a function like:

```
def useXX[T <: Tuple, X <: XX[T]](a:X, b:X): X = a
```

in **Dotty/Scala 3** that ensures that the singleton types of `XX[T]`

in the function parameters `a`

and `b`

are the same. More concretely, the following should **fail** to compile:

```
val s3 = XX.xy((1,2,3))
val s4 = XX.xy((1,2,4))
val sr3 = useXX(s3, s4) // Error, should fail
```

Note that in general both `s3`

and `s4`

are of the type `(Int, Int, Int)`

, so compilation is successful. However the **singleton types** `(1, 2, 3)`

and `(1, 2, 4)`

do not match because `3.type`

and `4.type`

are not the same.

Now what do I mean by automate? If we declare the singletons explicitly:

```
val s1: XY[(1,2,3)] = XX.xy((1,2,3))
val s5: XY[(1,2,4)] = XX.xy((1,2,4))
val sr3 = useXX(s1, s5) // Ok, fails
```

then compilation fails. The problem is that now we depend on the programmer to declare these types explicitly. So we loose the advantage of typing. I think this an unsolved issue. I have tried using the `with Singleton`

to no avail.

So my question is, is there any way I can force compilation failure, even if it means demanding the programmer to explicitly provide the Singleton type?

TIA

If anyone wants to experiment, the code below can be found here:

```
sealed trait XX[T<:Tuple](val s:Array[Int])
object XX:
sealed case class XY[T<:Tuple] private[XX] (override val s:Array[Int]) extends XX[T](s)
def xy[T<:Tuple](t:T): XY[T] =
val l = t.toArray.map(_.asInstanceOf[Int])
new XY(l)
import XX._
val t: (1,2,3) = (1,2,3)
val s0: XY[(1,2,3)] = XX.xy[(1,2,3)]((1,2,3))
val s1: XY[(1,2,3)] = XX.xy((1,2,3))
val s2 = XX.xy((1,2,4,5))
val s3 = XX.xy((1,2,3))
val s4 = XX.xy((1,2,4))
val s5: XY[(1,2,4)] = XX.xy((1,2,4))
// We need to explicitly use Singleton types
def useXX[T <: Tuple, X <: XX[T]](a:X, b:X): X = a
val sr0 = useXX(s0, s1)
//val sr1 = useXX(s0, s2) // Ok, fails
//val sr2 = useXX(s2, s3) // Ok, fails
val sr3 = useXX(s3, s4) // Error, should fail
//val sr3 = useXX(s1, s5) // Ok, fails
@main
def run: Unit =
// Nothing to do
println("Done")
()
```