2017-08-01 8 views
3

私は2つのHListを一緒に圧縮する方法を探しています。最初のものは、その汎用表現で変換されたケース・クラスから生成され、2番目はNatのHListとして手動で定義されます。Zip generic HList with static Nat HList

その結果、ケースクラスの1つのフィールドとNatが関連付けられたタプル(または2つのメンバHList)が必要です。

目的は、カスタマイズ可能な「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]と一致する必要があります。

+0

親愛なる@JulienLafontあなたは瞬間を持っているかどうかをチェックすることができますによってあなたの質問をするので、それがしばらくしています私の[answer](https://stackoverflow.com/a/45914883/5249621)がOKならば?ありがとうございました。 –

答えて

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) 
関連する問題