|
1 | 1 | package scala |
2 | | -import annotation.showAsInfix |
| 2 | +import annotation.{ showAsInfix, implicitNotFound } |
3 | 3 | import compiletime._ |
4 | 4 | import internal._ |
5 | 5 |
|
@@ -74,6 +74,27 @@ object Tuple { |
74 | 74 | case h *: t => F[h] *: Map[t, F] |
75 | 75 | } |
76 | 76 |
|
| 77 | + /** Converts a tuple `(F[T1], ..., F[Tn])` to `(T1, ... Tn)` */ |
| 78 | + type InverseMap[X <: Tuple, F[_]] <: Tuple = X match { |
| 79 | + case F[x] *: t => x *: InverseMap[t, F] |
| 80 | + case Unit => Unit |
| 81 | + } |
| 82 | + type IsInverseMap[F[_]] = [X <: Tuple] =>> Tuple.IsInverseMap.PredicateAux[X, F, InverseMap[X, F]] |
| 83 | + object IsInverseMap { |
| 84 | + sealed trait Predicate[X <: Tuple, F[_]] { type Result <: Tuple } |
| 85 | + type PredicateAux[X <: Tuple, F[_], R] = Predicate[X, F] { type Result = R } |
| 86 | + |
| 87 | + given [X <: NonEmptyTuple, F[_], H, T <: Tuple] as PredicateAux[X, F, H *: T] given ( |
| 88 | + e1: Head[X] =:= F[H], |
| 89 | + e2: PredicateAux[Tail[X], F, T]) = new Predicate[X, F] { |
| 90 | + type Result = H *: T |
| 91 | + } |
| 92 | + |
| 93 | + given [F[_]] as PredicateAux[Unit, F, Unit] = new Predicate[Unit, F] { |
| 94 | + type Result = Unit |
| 95 | + } |
| 96 | + } |
| 97 | + |
77 | 98 | /** Convert an array into a tuple of unknown arity and types */ |
78 | 99 | def fromArray[T](xs: Array[T]): Tuple = { |
79 | 100 | val xs2 = xs match { |
|
0 commit comments