代码之家  ›  专栏  ›  技术社区  ›  Terry Dactyl

无形状-泛型Repr类型操纵

  •  0
  • Terry Dactyl  · 技术社区  · 6 年前

    如果我有以下方法:

            def f[T: Generic, U: Generic](t: T): U
    

    Generic[T].to(t) 返回类型 Generic[T]#Repr 我假设它是某种类型HList的类型别名。

    可以从列表中选择成员吗 HList 再建一座 赫利斯特 我可以确信编译器是 Generic[U]#Repr 然后我可以用它来创建 U 使用 Generic[U].from(myNewHList) ?

    0 回复  |  直到 6 年前
        1
  •  3
  •   Ethan    6 年前

    当你在无形中做这样的事情时,最好的地方是在 shapeless.ops 打字课。在这种情况下,因为你知道你的第二个类是第一个类的严格子集, Intersection 足以得到你想要的。您需要将其设置为一个类型类,以便传入输入和输出类型,并让编译器推断中间内容。

    trait Converter[A,B] {
      def convert(a: A): B
    }
    object Converter {
      def apply[A,B](implicit converter: Converter[A,B]) = converter
    
      implicit def genericConverter[A, B, ARepr <: HList, BRepr <: HList](
        implicit
        genA: Generic.Aux[A,ARepr],
        genB: Generic.Aux[B,BRepr],
        intersection: shapeless.ops.hlist.Intersection.Aux[ARepr,BRepr,BRepr]
      ): Converter[A,B] = 
        new Converter[A,B]{def convert(a: A): B = genB.from(intersection(genA.to(a)))}
    }
    

    这可以按如下方式使用:

    case class Foo(a: Int, b: Int, c: String)
    case class Bar(a: Int, c: String)
    val foo = Foo(1,2,"Three")
    val bar: Bar = Converter[Foo, Bar].convert(foo)