shapeless HList to TupleN, wobei die Tupelform nicht genau mit der HList-Form übereinstimmen muss

Ich möchte das Äquivalent erstellen zu:

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

Code usingtoTupleN sollte nur kompilieren, wenn es genau ein @ giN Kombination von Werten inl dass das Tupel aus erstellt werden konnte. Alles andere sollte einen Fehler beim Kompilieren verursachen. Verfügbare implizite Konvertierungen sollten berücksichtigt werden. Beachten Sie, dass es keine Einschränkungen für die Größe von @ gibl oder die Reihenfolge der Werte darin.

Beispiel

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

Diese Frage ergab sich aus demAntworte Zu dem FolgendemFrag. Die allgemeinere Maschinerie in dieser Frage könnte verwendet werden, um Datenstrukturen zu erstellen und eine Standardfunktion (deren Argumente von unterschiedlichem Typ sind) mit @ aufzurufeFunctionN#tupled.

Aktualisieren

Einige Beispiele zum Definieren des gewünschten Verhaltens mit Untertypen:

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

Antworten auf die Frage(2)

Ihre Antwort auf die Frage