Zip Generic HList with static Nat HList

I am looking for a way to pin two HLists together. The first one is generated from the case class converted to its generic representation, and the second one is manually defined as an HList from Nat.

As a result, I expect a tuple (or 2-member HList) with one field from the case class, and the associated Nat.

The goal is to create "custom" 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]

      

The result must match encoderTuple[H, N <: Nat, T <: HList]: Encoder[(H, N) :: T]

either or encoderHList[H, N <: Nat, T <: HList]: Encoder[(H::N::HNil) :: T]

.

+3


source to share


1 answer


The goal is to create "custom" ZipWithIndex

.

I guess the standard shapeless.ops.hlist.Zip is enough for this:



  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)

      

+1


source







All Articles