2016-07-30 8 views
3

Ich habe eine hList von Strings:Karte ein homogenes hList eines Typs in eine hetergenous hList verschiedenen Typen

val strings = "The Lorax" :: "Dr. Suess" :: HNil 

mir eine anderen hList von speziellen Typen:

case class Title(title: String, words: List[String]) 
case class Author(firstName: String, lastName: String) 
val book = Title("The Hobbit", List("Hobbit")) :: Author("J.R.R.", "Tolkien") :: HNil 

ich machen will " Strings ", mein HList von Strings, in ein HList gemischter Typen, entsprechend der" Buch "-Liste. Wenn ich eine Methode habe, von einer Zeichenkette zu gehen -> Titel, und eine Methode, um von einer Zeichenkette -> Autor zu gehen, denke ich, dass dies sehr geradlinig sein sollte, um "Zeichenketten" als eine Instanz der "Buch" -Liste zu erhalten -Typ mit formlos, aber ich kann nicht scheinen, einen Weg zu finden.

EDIT

für Meine Use Case beinhaltet auf HLists arbeiten, die als Fallklassen gestartet. Ich verwende formlos, weil ich in der Lage sein möchte, die Daten verschiedener Fallklassen auf die gleiche Weise zu transformieren und zu modifizieren, ohne das Wissen über die Form der Fallklassen fest codieren zu müssen. Ich möchte nur etwas über das wissen Arten ihrer Werte. So ideal wäre diese Methode funktioniert auch für Sie aus einer Liste von Strings gehen, die wie folgt aussieht:

val strings2 = "Leonardo" :: "April O'Neil" :: "The Art of Pizza" :: HNil 
val book2 = Author("Michaelangelo") :: Author("Donatello") :: Title("Slicing and Dicing"), List("Slicing", "Dicing") :: HList 

So werde ich immer ein Beispiel für das Format haben, es in sein muss, aber ich will nicht haben, die Anzahl der "Autoren" und die Anzahl der "Bücher" in eine Liste von Übersetzungsfunktionen zu kodieren. Ich möchte sagen können "a, a, b" sollte wie "A, A, B" aussehen, und hier ist eine Methode von "a -> A" und hier ist eine Methode von "b ->" zu gehen B ", aber ich möchte in der Lage sein, den gleichen Code zu verwenden, um von" b, a, b "zu" B, A, B "zu gehen, vorausgesetzt, dass ich beide Listen habe.

Antwort

2

du mit zipApply ziemlich gut tun, die jedes Element eines hList von Funktionen auf das entsprechende Element in einem anderen hList gilt:

case class Title(title: String, words: List[String]) 
case class Author(firstName: String, lastName: String) 

// For the sake of example: 
def parseTitle(s: String): Title = Title(s, s.split(' ').toList) 
def parseAuthor(s: String): Author = 
    Author(s.takeWhile(_ != ' '), s.dropWhile(_ != ' ').tail) 

import shapeless._ 

val funcs = parseTitle _ :: parseAuthor _ :: HNil 
val strings = "The Lorax" :: "Dr. Suess" :: HNil 

val book = funcs.zipApply(strings) 

Und dann:

scala> println(book) 
Title(The Lorax,List(The, Lorax)) :: Author(Dr.,Suess) :: HNil 

Wenn Sie brauchen Um generischer zu sein, können Sie die Typenklasse ZipApply verwenden, statt einfach zipApply auf Listen mit konkreten Typen aufzurufen.

+0

Vielen Dank für die schnelle Rückkehr zu mir Travis !! Ich habe die Frage bearbeitet, weil ich fürchte, dass zipApply für meine Situation nicht wirklich funktioniert. Ich habe auch versucht, etwas konkretere und ausführlichere Fragen [hier] zu stellen (http://stackoverflow.com/questions/38684994/using-shapeless-to-extract-data-from-case-classes-modify-it-and-recreate -the-c) nur für den Fall, dass es keinen einfachen Weg gibt, das zu tun, was ich versuche, und ich nähere mich dem Problem aus dem falschen Blickwinkel. Wie auch immer, danke !! –