将一个类型的同质HList映射为不同类型的异质HList



我有一个字符串的HList:

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

I特殊类型的另一个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"列表。如果我有一个从字符串->标题的方法,和一个从string->作者的方法,我觉得这应该是非常直接的,基本上可以使用shapeless将"string"作为"book"列表类型的实例,但我似乎想不出一种方法。

编辑

我的这个用例涉及到处理以案例类形式开始的HList。我使用shapeless是因为我希望能够以相同的方式转换和修改不同事例类的数据,而不必对有关事例类的形状的知识进行硬编码,我只想知道它们值的类型。因此,理想情况下,这种方法也适用于从如下字符串列表中提取:

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

使用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类型类,而不是简单地在具有具体类型的hlist上调用zipApply

最新更新