Shapeless LabelledGeneric 但忽略了一些字段 [英] Shapeless LabelledGeneric but ignoring some fields

查看:51
本文介绍了Shapeless LabelledGeneric 但忽略了一些字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想定义一个无形的LabelledGeneric,它在转换为HList 时忽略一个(或多个)字段;当再次将 HList 转换回来时,它应该替换用户定义的值.目标是能够写出这样的东西:

I would like to define a shapeless LabelledGeneric that ignores one (or more) fields when converting to HList; when converting the HList back again it should substitute a user-defined value. The goal is to be able to write something like this:

case class Foo(i: Int, s: String)
val foo = Foo(123, "Hello")

val gen = LabelledGeneric[Foo].ignoring('i)(defaultValue = -1)
val hlist = gen.to(foo)
// "Hello" :: HNil

val foo2 = gen.from(hlist)
assert(foo2 == Foo(-1, "Hello"))

这是我目前所拥有的.它可以编译,但是当我尝试使用它时,我无法让类型正确排列以进行隐式解析:

This is what I have so far. It compiles, but I can't get the types to line up properly for implicit resolution when I try to use it:

implicit class IgnoringOps[T](orig: LabelledGeneric[T]) {
  def ignoring[Orig <: HList, V, Ign <: HList](k: Witness)(defaultValue: V)(implicit
   gen: LabelledGeneric.Aux[T, Orig],
   rem: Remover.Aux[Orig, FieldType[k.T, V], Ign],
   upd: Updater.Aux[Ign, FieldType[k.T, V], Orig]): LabelledGeneric[T] = {
    new LabelledGeneric[T] {
      override type Repr = Ign
      override def to(t: T): Ign = rem(gen.to(t))
      override def from(r: Ign): T = gen.from(upd(r, field[k.T](defaultValue)))
    }
  }
}

谁能解释一下我做错了什么?

Can anyone shed any light on what I'm doing wrong?

推荐答案

这应该按预期工作(根据您的示例):

This should work as intended (as per your example):

  implicit class IgnoringOps[T, L <: HList](gen: LabelledGeneric.Aux[T, L]) {
    def ignoring[V, I <: HList, H <: HList](k: Witness)(v: V)(implicit
      rem: Remover.Aux[L, k.T, (V, I)],
      upd: Updater.Aux[I, FieldType[k.T, V], H],
      ali: Align[H, L]
    ): LabelledGeneric[T] = new LabelledGeneric[T] {
      override type Repr = I

      //`rem` is implicitly used there
      override def to(t: T): I = gen.to(t) - k

      //`upd` and `ali` are implicitly used there
      override def from(r: I): T = gen.from(r + field[k.T](v))
    }
  }

注意事项:

  • ignoring中移除了隐式参数gen: LabelledGeneric.Aux[T, L],你可以利用隐式类参数orig;
  • 使用来自 RecordOps 而不是显式使用 remupd;
  • 更新了 rem 隐式参数Remover.Aux[L, FieldType[kT, V], I],Remover.Aux[L, kT,(V, I)];
  • 添加了中间助手 H <: HList;
  • 更新upd隐式参数,使用前面提到的中间助手,从Updater.Aux[I, FieldType[kT, V], L]Updater.Aux[I, FieldType[kT, V], H];
  • 添加 ali 隐式要求 HL 对齐:ali: Align[H, L]
  • Removed implicit parameter gen: LabelledGeneric.Aux[T, L] from ignoring, you can leverage implicit class parameter orig;
  • Used - and + methods from RecordOps instead of using explicitly rem and upd;
  • Updated rem implicit parameter from Remover.Aux[L, FieldType[k.T, V], I], to Remover.Aux[L, k.T, (V, I)];
  • Added intermediate helper H <: HList;
  • Updated upd implicit parameter, using aforementioned intermediate helper, from Updater.Aux[I, FieldType[k.T, V], L] to Updater.Aux[I, FieldType[k.T, V], H];
  • Added ali implicitly asking for alignment of H and L: ali: Align[H, L]

这篇关于Shapeless LabelledGeneric 但忽略了一些字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆