gpt4 book ai didi

scala - 与不同类型但相同标签的无形状对齐

转载 作者:行者123 更新时间:2023-12-01 16:13:57 25 4
gpt4 key购买 nike

有人知道如何对齐两个记录,当它们具有相同的字段名称但不同的值时,一个记录包含在列中,另一个记录包含在选项中,并且我需要对齐它们,因为顺序不同

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)

}

}

我可以对齐具有完全相同类型的两条记录,并且即使类型不完全相同,我也可以对两条记录执行 zipWith,但它们需要通过键对齐。

谢谢

最佳答案

如果我们忽略字段名称的相似性并专注于类型,我们可以执行以下操作:

    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

关于scala - 与不同类型但相同标签的无形状对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45863795/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com