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