将带有静态 Nat HList 的通用 HList 进行压缩

3
我正在寻找一种方法将两个HList压缩在一起。第一个HList是从一个转换为其通用表示的case类生成的,第二个HList是手动定义的Nat类型的HList。
因此,我期望得到一个元组(或具有两个成员的HList),其中包含来自case类的一个字段和相关联的Nat类型。
目标是创建一个“可定制”的ZipWithIndex。
def derive[A, I <: HList, R <: HList, Z <: HList](implicit 
  gen: Generic.Aux[A, R],
  zipper: Zip.Aux[R, I, Z],
  enc: Lazy[Encoder[Z]])(a: A): Deriver[A] = {
    val genRepr = gen.to(A)
    val zipped = zip(genRepr :: ??? :: HNil)
    enc.value(zipped)
}

case class Foo(a: String, b: String, c: String)
derive[Foo, Nat._1 :: Nat._3 :: Nat.7 :: HNil]

结果必须与encoderTuple[H,N <:Nat,T <:HList]:Encoder [(H,N):: T]encoderHList[H,N <:Nat,T <:HList]:Encoder [(H :: N :: HNil):: T]匹配。


亲爱的@JulienLafont,自从您提出问题以来已经有一段时间了,如果您有时间,可以检查一下我的答案是否正确吗?谢谢。 - Dmytro Mitin
1个回答

1
目标是创建一个可自定义的“ZipWithIndex”。我想标准的shapeless.ops.hlist.Zip应该足够了:
  trait Encoder[Z] {
    type Out
    def apply(z: Z): Out
  }

  object Encoder {
    type Aux[Z, Out0] = Encoder[Z] { type Out = Out0 }

    // implicits
  }

  trait Deriver[A]

  object Deriver {
    // implicits
  }

  def derive[A, I <: HList, R <: HList, Z <: HList](a: A, i: I)(implicit
                                                    gen: Generic.Aux[A, R],
                                                    zipper: Zip.Aux[R :: I :: HNil, Z],
                                                    enc: Lazy[Encoder.Aux[Z, Deriver[A]]]): Deriver[A] = {
    val genRepr: R = gen.to(a)
    val zipped: Z = zipper(genRepr :: i :: HNil)
    enc.value(zipped)
  }

  case class Foo(a: String, b: String, c: String)
//  derive[Foo, Nat._1 :: Nat._3 :: Nat._7 :: HNil, ???, ???]
  derive(Foo("aaa", "bbb", "ccc"), Nat._1 :: Nat._3 :: Nat._7 :: HNil)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接