I have this perfectly working match type along with its function:
type Find[Columns <: Tuple, Label] =
Columns match
case TypedColumn[Label] *: ? => TypedColumn[Label]
case TypedColumn[?] *: t => Find[t, Label]
inline def findT[C <: Tuple, Label <: Singleton]: Find[C, Label] =
erasedValue[C] match
case _: (TypedColumn[Label] *: ?) =>
TypedColumn[Label](constValue[Label], None)
case _: (TypedColumn[?] *: tail) =>
findT[tail, Label]
Which basically exists to reify an object from a homogeneous tuple. The type itself has signature like TypedColumn[L <: Singleton](smth: Option[Something])
(the type has many compile-time labels, but I’m omitting them for sake of brevity) and this function works fine, but when I try to implement the same for multiple labels:
// Match type is fine
type Pick[Columns <: NonEmptyTuple, Labels <: Tuple] <: Tuple =
Labels match
case l *: t => Find[Columns, l] *: Pick[Columns, t]
// I can't prove that my `h` is a Singleton
inline def pickT[C <: NonEmptyTuple, Labels <: Tuple]: Pick[C, Labels] =
erasedValue[Labels] match
case _: (h *: t) =>
findT[C, h] *: pickT[C, t]
Tried to create ad-hoc type classes with Out
singleton, IsConst
type, Mirror.Singleton
etc, but all of them break the function.
The end-goal would be to have something like:
type In = (TypedColumn["one"], TypedColumn["two"], TypedColumn["three"])
pickT[In, ("two", "one")]
// evaluating to runtime value of:
(TypedColumn(None), TypedColumn(None)): (TypedColumn["two"], TypedColumn["one"])
The error is:
[error] 233 | findT[C, h] *: pickT[C, t]
[error] | ^
[error] | Type argument h does not conform to upper bound Singleton