2016-07-30 5 views
3

У меня есть HList строк:Карта гомогенную HList одного типа в hetergenous HList различных типов

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

Я еще HList специальных типов:

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 

Я хочу, чтобы включить " строки ", мой HList строк, в HList смешанных типов, соответствующих списку" book ". Если у меня есть метод перейти от строки -> Заголовок и метод для перехода от строки -> Автор, я чувствую, что это должно быть очень просто, чтобы по существу получить «строки» в качестве экземпляра «book» -list типа с бесформенным, но я не могу понять, каким образом.

EDIT

Мой случай использования для этого включает в себя работу по HLists, начавшихся в случае классов. Я использую бесформенность, потому что я хочу иметь возможность трансформировать и модифицировать данные разных классов case одинаковым образом, не имея необходимости жестко кодировать знания о форме классов case, я хочу знать только о типы их значений. Таким образом, в идеале этот метод будет работать также для выхода из списка строк, выглядит следующим образом:

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 

Так что я всегда буду иметь пример формата он должен быть, но я не хочу иметь для жесткого кодирования количества «авторов» и количества «книг» в список функций перевода. Я хочу сказать, что «a, a, b» должно выглядеть как «A, A, B», и вот этот метод идет от «a -> A», и вот способ перехода от «b -> B ", но я хочу иметь возможность использовать тот же код, чтобы перейти от" b, a, b "в" B, A, B ", учитывая, что у меня есть оба списка.

ответ

2

Вы можете сделать это довольно красиво с zipApply, который применяется каждый элемент hlist функций к соответствующему элементу в другом hlist:

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) 

А потом:

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

Если вам нужно это будет более общим, вы можете использовать класс типа ZipApply вместо простого вызова zipApply на hlists с конкретными типами.

+0

Спасибо, что вернулись ко мне так быстро, Трэвис! Я редактировал вопрос, потому что боюсь, что zipApply действительно не работает для моей ситуации. Я также попробовал задать более конкретный и подробный вопрос [здесь] (http://stackoverflow.com/questions/38684994/using-shapeless-to-extract-data-from-case-classes-modify-it-and-recreate -s-c) на всякий случай, если нет простого способа сделать то, что я пытаюсь сделать, и я подхожу к проблеме из-за неправильного угла. В любом случае, спасибо! –