scala - 拆分使用Prepend [A,B]串联的HList

标签 scala shapeless

我本质上是在寻找类型类Prepend[A, B]的反义词。

如果我有类似的东西:

type A = String :: Int :: HNil
type B = Boolean :: Double :: HNil

val a: A = "a" :: 1 :: HNil
val b: B = false :: 2.1 :: HNil

scala> val ab = a ++ b
ab: shapeless.::[String,shapeless.::[Int,shapeless.::[Boolean,shapeless.::[Double,shapeless.HNil]]]] = a :: 1 :: false :: 2.1 :: HNil

我有一个HList类型的a A和一个HList类型的b B,我可以找到一个prepend: Prepend[A, B],以便可以将它们与a ++ b连接起来。

但是,如果我有一个HList类型的ab prepend.Out,如何提取原始的AB?我似乎找不到能胜任工作的类型类,也许没有。似乎我需要像trait Cut[A <: HList, B <: HList, c <: HList]这样的东西来见证C是通过将A前置在B之上而创建的,尽管我不确定如何去生成见证人。

非常大致像:
def Cut[A <: HList, B <: HList, C <: HList](c: C)(implicit cut: Cut[A, B, C]): (A, B)  = ???

最佳答案

您可以使用Split相当直接地做到这一点:

import shapeless._, ops.hlist.{ Length, Prepend, Split }

class UndoPrependHelper[A <: HList, B <: HList, C <: HList, N <: Nat] {
  def apply(c: C)(implicit split: Split.Aux[C, N, A, B]): (A, B) = split(c)
}

def undoPrepend[A <: HList, B <: HList](implicit
  prepend: Prepend[A, B],
  length: Length[A]
) = new UndoPrependHelper[A, B, prepend.Out, length.Out]

然后:
scala> type A = Int :: String :: Symbol :: HNil
defined type alias A

scala> type B = List[Int] :: Option[Double] :: HNil
defined type alias B

scala> type C = Int :: String :: Symbol :: List[Int] :: Option[Double] :: HNil
defined type alias C

scala> val a: A = 1 :: "foo" :: 'bar :: HNil
a: A = 1 :: foo :: 'bar :: HNil

scala> val b: B = List(1, 2, 3) :: Option(0.0) :: HNil
b: B = List(1, 2, 3) :: Some(0.0) :: HNil

scala> val c: C = a ++ b
c: C = 1 :: foo :: 'bar :: List(1, 2, 3) :: Some(0.0) :: HNil

scala> val (newA: A, newB: B) = undoPrepend[A, B].apply(c)
newA: A = 1 :: foo :: 'bar :: HNil
newB: B = List(1, 2, 3) :: Some(0.0) :: HNil

我对Remove类型类recently added进行了“撤消”操作,并且在Prepend中内置了类似的内容可能是有意义的。

关于scala - 拆分使用Prepend [A,B]串联的HList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32366527/

相关文章:

scala - 我们可以有一组按名称参数的函数吗?

scala - Spark Scala Dataframe 描述非数字列

scala - 固定大小和元素边界的 Nat 列表

scala - 与不同类型但相同标签的无形状对齐

scala - 对连续元素具有类型约束的列表

scala - 案例类 - 通过转换复制多个字段

scala - 按类型选择字段

scala - AUX 模式解决方法

scala - 如果单例如此糟糕,为什么 Scala 为它们提供语言支持?

scala - 使用 .toSet 制作的 Set 上的类型推断失败?