首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >List of HLists to HList of Lists?

List of HLists to HList of Lists?
EN

Stack Overflow用户
提问于 2018-03-09 05:15:09
回答 1查看 166关注 0票数 0

基本上,我想要转置我的对象。有没有简单的方法可以做到这一点?如果我的HList很大,我不想折叠。

这是为了解压一个高元组的列表。

EN

回答 1

Stack Overflow用户

发布于 2018-03-09 07:33:21

我不知道现有的解决方案,但这似乎是一个有趣的任务,所以我尝试了一下。

假设我们有一个HLists的列表,比如

代码语言:javascript
复制
val myList: List[Int :: String :: Boolean :: HNil] = List(
  1 :: "sample1" :: true :: HNil,
  2 :: "sample2" :: false :: HNil,
  3 :: "sample3" :: true :: HNil
)

我们想要一个列表的HList,比如

代码语言:javascript
复制
val expected: List[Int] :: List[String] :: List[Boolean] :: HNil = 
  List(3, 2, 1) :: 
  List("sample3", "sample2", "sample") :: 
  List(true, false, true) ::
  HNil

我们需要创建一个类型类。我把它命名为EmptyOf。它只有一个方法可以创建一个包含空列表的HList。

代码语言:javascript
复制
trait EmptyOf[T <: HList, AsList <: HList] {
  def empty: AsList
}

下面是HNil的实现:

代码语言:javascript
复制
implicit val emptyOfHNil: EmptyOf[HNil, HNil] = () => HNil

现在来看看HCons:

代码语言:javascript
复制
implicit def emptyOfHCons[H, T <: HList, TEmpty <: HList](
  implicit ev: EmptyOf[T, TEmpty]
): EmptyOf[H :: T, List[H] :: TEmpty] = () => List.empty[H] :: ev.empty()

因此,对于EmptyOf[T :: U :: HNil, List[T] :: List[U] :: HNil],我们的实例的empty将返回Nil :: Nil :: HNil

有了这些,我们可以通过折叠HLists列表并使用Poly2合并HLists来实现HLists。

代码语言:javascript
复制
object concat extends Poly2 {
  implicit def prepend[S] = at[List[S], S]((list, s) => s :: list)
}

def transpose[T <: HList, U <: HList](lists: List[T])
                                     (implicit emptyOf: EmptyOf[T, U],
                                      zip: ZipWith.Aux[U, T, concat.type, U]): U =
  lists.foldLeft(emptyOf.empty())(_.zipWith(_)(concat))

现在transpose(myList)应该等于expected (并且是正确的类型)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49182575

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档