2017-08-24 4 views
4

同じ名前のフィールドでも同じ値ではなく2つのレコードを整列させる方法を知っていますか?別のものがOptionで折り返された値を持ちます。順序は、私はまったく同じタイプの2つのレコードを揃えることができ、タイプが1つを強要されていないが、彼らはキーで整列する必要がある場合でも、私は2つのレコードをzipWithを行うことができます異なるタイプの同じラベルを整列させた形の整列

import shapeless._ 
import shapeless.labelled.{FieldType, field} 
import shapeless.ops.hlist.{Align, ToTraversable, ZipWith} 

object ShapelessTest { 


    def zipClasses[A, B, P <: Poly2, ARepr <: HList, BRepr <: HList, R <: HList, X] 
    (a: A, b: B, f: P)(
    implicit 
    aGen : LabelledGeneric.Aux[A, ARepr], 
    bGen : LabelledGeneric.Aux[B, BRepr], 
// align : Align[ARepr, BRepr], 
    zipWith : ZipWith.Aux[ARepr, BRepr, P, R], 
    toTrav: ToTraversable.Aux[R, List, X] 
): List[X] = 
    aGen.to(a).zipWith(bGen.to(b))(f).toList 
// align.apply(aGen.to(a)).zipWith(bGen.to(b))(f).toList 



    def main(args: Array[String]): Unit = { 


    case class Column[A](value: A) 

    case class DTable(id: Column[Long], s2: Column[Int], s: Column[String]) 
    case class DFilter(id: Option[Long], s: Option[String], s2: Option[Int]) 

    object filter extends Poly2 { 
     implicit def repr[K <: Symbol, V] = at[FieldType[K, Column[V]], FieldType[K, Option[V]]] { (a, b) => 
     field[K]((a, b).asInstanceOf[(Any, Any)]) 
     } 
    } 

    val dTable = new DTable(Column(1L), Column(3), Column("s")) 
    val dFilter = new DFilter(Option(222L), Option("second"), Option(234)) 


// def filter[A](col: Column[A], filterCriteria: Option[A]): Option[Boolean] = ??? 

// def filterClass(table: DTable, filter: DFilter): List[Option[Boolean]] = ??? 
    def filterClass(t: DTable, f: DFilter): List[(Any, Any)] = zipClasses(t, f, filter) 

    val res = filterClass(dTable, dFilter) 
    println(res) 

    } 

} 

異なっています。我々は、フィールド名に類似性を無視して、私たちは次の操作を行うことができます種類に焦点を当てた場合

はあなたに

答えて

2

ありがとう:

def alignRecordByTypeInsideConstructor[A, B, L1 <: HList, L2 <: HList, 
     F[_], G[_], L3 <: HList, L4 <: HList, Out <: HList](a: A, b: B, f: F ~> Id, g: Id ~> G)(
     implicit 
     gen1: Generic.Aux[A, L1], 
     gen2: Generic.Aux[B, L2], 
     comapped1: Comapped.Aux[L1, F, L3], 
     natTRel1: NatTRel[L1, F, L3, Id], 
     comapped2: Comapped.Aux[L2, G, L4], 
     natTRel2: NatTRel[L2, G, L4, Id], 
     align: Align[L3, L4], 
     mapped: Mapped.Aux[L4, G, Out], 
     natTRel3: NatTRel[L4, Id, Out, G] 
    ): Out = 
     alignByTypeInsideConstructor[L1, L2, F, G, L3, L4, Out](gen1.to(a), gen2.to(b), f, g) 

    def alignByTypeInsideConstructor[L1 <: HList, L2 <: HList, 
     F[_], G[_], L3 <: HList, L4 <: HList, Out <: HList](l1: L1, l2: L2, f: F ~> Id, g: Id ~> G)(
     implicit 
     comapped1: Comapped.Aux[L1, F, L3], 
     natTRel1: NatTRel[L1, F, L3, Id], 
     comapped2: Comapped.Aux[L2, G, L4], 
     natTRel2: NatTRel[L2, G, L4, Id], 
     align: Align[L3, L4], 
     mapped: Mapped.Aux[L4, G, Out], 
     natTRel3: NatTRel[L4, Id, Out, G]): Out = 
     natTRel3.map(g, align(natTRel1.map(f, l1))) 

    object columnToId extends (Column ~> Id) { 
     override def apply[A](column: Column[A]): A = column match { 
     case Column(a) => a 
     } 
    } 

    object idToOption extends (Id ~> Option) { 
     override def apply[A](a: A): Option[A] = Some(a) 
    } 

    alignByTypeInsideConstructor(
     Column(1L) :: Column(2) :: Column("a") :: HNil, 
     Option(3L) :: Option("b") :: Option(4) :: HNil, 
     columnToId, 
     idToOption 
    ) 

    //Some(1) :: Some(a) :: Some(2) :: HNil 

    alignRecordByTypeInsideConstructor(
     DTable(Column(1L), Column(2), Column("a")), 
     DFilter(Option(3L), Option("b"), Option(4)), 
     columnToId, 
     idToOption 
    ) 

    //Some(1) :: Some(a) :: Some(2) :: HNil 
+1

はあなたにドミトロありがとう – user1698641

関連する問題