Заархивируйте универсальный HList со статическим Nat HList

Я ищу способ объединить два HList. Первый генерируется из case-класса, преобразованного в его универсальное представление, а второй определяется вручную как HList Nat.

В результате я ожидаю кортеж (или 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].


person Julien Lafont    schedule 01.08.2017    source источник
comment
Уважаемый @JulienLafont, прошло некоторое время с тех пор, как вы задали свой вопрос, если у вас есть минутка, можете ли вы проверить, является ли мой ответ ОК? Спасибо.   -  person Dmytro Mitin    schedule 30.08.2017


Ответы (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)
person Dmytro Mitin    schedule 28.08.2017