0

从我在线阅读的内容来看,无形 Record.updateWith 似乎是更新 Record 条目的值和类型的唯一方法。所以我试了一下:


  import shapeless.syntax.singleton.mkSingletonOps
  import shapeless.record._

    val existing = ("i" ->> 3.0) :: ("j" ->> "Abc") :: HNil

    val uu = existing.updateWith("i")(_ => 123)

有效!输出是123 :: Abc :: HNil,但是我遇到了一个不同的问题:我不能在另一个函数中调用这个函数,即它不能在范围内使用类型类:

    def update[HH <: HList, O](existing: HH, k: Witness.Lt[String], v: Int)(
        implicit
        lemma1: Selector.Aux[HH, k.T, O],
        lemma2: Modifier[HH, k.T, O, Int]
    ) = {

      val result = existing.updateWith(k.value)(_ => v)
      result
    }

最新的编译器(2.13.4)给出了以下错误信息:

[Error] ... : Unable to resolve implicit value of type shapeless.ops.record.Selector[HH,Witness.this.value.type]
one error found

尽管如此,这lemma1完全符合这种条件。所以我的问题是:

  • 我如何指示使用的类型类召唤updateWithlemma1?(它是用宏写的)

  • 如果这是不可能的,在方法中实现正确更新的其他选择是什么?

非常感谢你的帮助

4

1 回答 1

1

尽管 lemma1 完全符合这个条件。

不,它没有。Selector[HH, k.T]并且Selector[HH, k.value.type]是不同的类型。k.value.type是 的子类型k.TSelector是不变的。

我已经建议你使用类型类而不是扩展方法

def update[HH <: HList, O](existing: HH, k: Witness.Lt[String], v: Int)(
  implicit
  lemma1: Selector.Aux[HH, k.T, O],
  lemma2: Modifier[HH, k.T, O, Int]
) = {
  lemma2(existing, _ => v)
}

或者

def update[HH <: HList, K <: String, O](existing: HH, k: K, v: Int)(
  implicit
  witness: Witness.Aux[K],
  lemma1: Selector.Aux[HH, K, O],
  lemma2: Modifier[HH, K, O, Int]
) = {
  lemma2(existing, _ => v)
}
于 2021-02-28T22:33:14.820 回答