简体   繁体   English

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

[英]Map a homogenous HList of one type into a hetergenous HList of different types

I have an HList of strings: 我有一个字符串的HList:

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

I another HList of special types: 我是另一个特殊类型的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

I want to turn "strings", my HList of strings, into an HList of mixed types, corresponding to the "book" list. 我想将“字符串”(我的字符串HList)转换为混合类型的HList,对应于“book”列表。 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. 如果我有一个方法来从一个字符串 - >标题,一个方法来一个字符串 - >作者,我觉得这应该是非常直接的基本上得到“字符串”作为“书”的实例 - 列表 - 使用无形的类型,但我似乎无法找到一种方法。

EDIT 编辑

My use case for this involves working on HLists that started as case classes. 我的用例涉及到作为案例类开始的HLists。 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 

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. 我希望能够说“a,a,b”应该看起来像“A,A,B”,这里有一个方法来自“a - > A”,这里是一个方法,从“b - > B“,但我希望能够使用相同的代码从”b,a,b“到”B,A,B“,因为我有两个列表。

You can do this pretty nicely with zipApply , which applies each element of an hlist of functions to the corresponding element in another hlist: 你可以使用zipApply很好地完成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)

And then: 然后:

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

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. 如果您需要更通用,则可以使用ZipApply类型类,而不是简单地在具有类型的zipApply上调用zipApply

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM