基本上我想转置我的对象。有一个简单的方法吗?如果我的HList很大而且我不想弃牌。
这是解压缩高级元组列表的服务。
答案 0 :(得分:0)
我不知道现有的解决方案,但这似乎是一项有趣的任务,所以我尝试了它。
假设我们有一个HLists列表,比如
val myList: List[Int :: String :: Boolean :: HNil] = List(
1 :: "sample1" :: true :: HNil,
2 :: "sample2" :: false :: HNil,
3 :: "sample3" :: true :: HNil
)
我们想要一个列表的HList,比如
val expected: List[Int] :: List[String] :: List[Boolean] :: HNil =
List(3, 2, 1) ::
List("sample3", "sample2", "sample") ::
List(true, false, true) ::
HNil
我们需要创建一个类型类。我把它命名为EmptyOf
。它有一个方法可以创建一个包含空列表的HList。
trait EmptyOf[T <: HList, AsList <: HList] {
def empty: AsList
}
这是HNil的实现:
implicit val emptyOfHNil: EmptyOf[HNil, HNil] = () => HNil
现在对于HCons:
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列表并使用transpose
来合并HLists来实现Poly2
。
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
(以及正确的类型)。