I have the following type class (similar to skunk.Twiddler
):
/**
* A type class proving that `T` can be converted into an isomorphic Tuple of elements,
* each of which has `IsPrimtive[x]` instance or single-element Tuple if `x` is primtive already
*/
trait Dissect[T]:
type Out <: Tuple
def perform(t: T): Out
object Dissect:
type Aux[T, O] = Dissect[T] { type Out = O }
At some point later I need to combine:
Dissect[X] { type Out = (A, B) }
- …and
Dissect[Y] { type Out = (C, D) }
- …to get
Dissect[Z] { type Out = (A, B, C, D)}
But I cannot property extract Out
from a given Dissect
because type members are lost after summoning:
case class Foo(a: Int, b: String)
type T1 = Tuple.Map[(Int, Foo), Dissect]
// defined alias type T1
= (Dissect[Int], Dissect[Foo])
Now I want to convert T1
to (Int, (Int, String))
:
type IsTuple[T <: Tuple] = T
type Extract[D] <: Tuple = D match
case Dissect.Aux[?, IsTuple[t]] => t
type T2 = Tuple.Map[T1, Extract]
// defined alias type T2
= (Extract[Dissect[Int]], Extract[Dissect[String]])
So the compiler cannot reduce Extract[Dissect[Int]]
to Int *: EmptyTuple
(althought there’s such instance).
How do I get Out
?