HList sin forma a TupleN donde la forma de tupla no necesita coincidir exactamente con la forma HList

Me gustaría crear el equivalente de:

def toTupleN[A1, ..., AN, L <: HList](l: L): TupleN[A1, ..., AN]

Código usandotoTupleN debe compilarse solo cuando hay exactamente unoN combinación de valores enl a partir de la cual se podría crear la tupla. Cualquier otra cosa debería generar un error en tiempo de compilación. Las conversiones implícitas disponibles deben tenerse en cuenta. Tenga en cuenta que no hay restricciones en el tamaño del o el orden de los valores en él.

Ejemplo:

val l = 23 :: (1, "wibble") :: (2, "wobble") :: "foo" :: HNil
// l: shapeless.::[Int,shapeless.::[(Int, String),shapeless.::[(Int, String),shapeless.::[String,shapeless.HNil]]]] = 23 :: (1,wibble) :: (2,wobble) :: foo :: HNil

val t2: (String, Int) = toTuple2(l)
// t2: (String, Int) = (foo,23)

val nope: (String, String) = toTuple2(l)
// Compiler error because no combination of l's values can create nope

val nein: ((Int, String)) = toTuple2(l)
// Another compiler error because there is more than one way l's values can create nein

Esta pregunta surgió de laresponder a lo siguientepregunta. La maquinaria más general en esta pregunta podría usarse para crear estructuras de datos y llamar a cualquier función estándar (cuyos argumentos son de diferentes tipos) usandoFunctionN#tupled.

Actualizar:

Algunos ejemplos para definir el comportamiento deseado con subtipos:

trait A
trait B extends A
trait C extends A

val a: A
val b: B
val c: C

toTuple2[(A, Int)](5 :: b :: HNil)      // (b, 5): subtypes match supertypes when there is no exact match
toTuple2[(A, Int)](5 :: b :: a :: HNil) // (a, 5): only one exact match is available
toTuple2[(A, Int)](5 :: a :: a :: HNil) // compile error: more than one exact match is available
toTuple2[(A, Int)](5 :: b :: c :: HNil) // compile error: more than one inexact match is available

Respuestas a la pregunta(1)

Su respuesta a la pregunta