将一种类型的同构 HList 映射到不同类型的异构 HList [英] Map a homogenous HList of one type into a hetergenous HList of different types
问题描述
我有一个 HList 字符串:
I have an HList of strings:
val strings = "The Lorax" :: "Dr. Suess" :: HNil
我是另一个特殊类型的 HList:
I another HList of special types:
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
我想把strings",我的字符串HList,变成一个混合类型的HList,对应于book"列表.如果我有一种方法可以从字符串 -> 标题,以及一种方法可以从字符串 -> 作者,我觉得这应该非常简单,基本上可以将字符串"作为书"列表的实例-type 使用 shapeless,但我似乎想不出办法.
I want to turn "strings", my HList of strings, into an HList of mixed types, corresponding to the "book" list. If I have a method to go from a string -> Title, and a method to go from a string -> Author, I feel like this should be very straight forward to essentially get "strings" as an instance of "book"-list-type using shapeless, but I can't seem to figure out a way.
编辑
我的用例涉及处理作为案例类开始的 HList.我使用 shapeless 是因为我希望能够以相同的方式转换和修改不同案例类的数据,而不必对案例类的形状进行硬编码,我只想知道它们的值的类型.所以理想情况下,这种方法也适用于从看起来像这样的字符串列表:
My use case for this involves working on HLists that started as case classes. I'm using shapeless because I want to be able to transform and modify the data of different case classes in the same way, without having to hard-code knowledge about the shape of the case classes, I only want to have to know about the types of their values. So ideally this method would work also for going from a list of strings that looks like this:
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",因为我有两个列表.
So I will always have an example of the format it needs to be in, but I don't want to have to hardcode the amount of "authors" and the amount of "books" into a list of translation functions. I want to be able to say "a,a,b" should look like "A, A, B", and here is a method go from "a -> A" and here is a method to go from "b -> B", but I want to be able to use the same code to go from "b, a, b" to "B, A, B", given that I have both lists.
推荐答案
您可以使用 zipApply
很好地做到这一点,它将函数 hlist 的每个元素应用到另一个 hlist 中的相应元素:
You can do this pretty nicely with zipApply
, which applies each element of an hlist of functions to the corresponding element in another 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
.
If you need this to be more generic, you can use the ZipApply
type class instead of simply calling zipApply
on hlists with concrete types.
这篇关于将一种类型的同构 HList 映射到不同类型的异构 HList的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!