将一种类型的同源HList映射到不同类型的异类HList

时间:2016-07-30 20:09:58

标签: scala shapeless

我有一个字符串的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-type的实例,但我似乎无法找到方法。

修改

我的用例涉及处理以案例类开头的HLists。我正在使用无形,因为我希望能够以相同的方式转换和修改不同案例类的数据,而不必硬编码关于案例类形状的知识,我只想了解他们的价值观的类型。因此理想情况下,此方法也适用于从类似于此的字符串列表:

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“,因为我有两个列表。

1 个答案:

答案 0 :(得分:2)

你可以很好地使用zipApply,它将函数列表的每个元素应用到另一个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类型类,而不是简单地在具有类型的hlists上调用zipApply