在 scala shapeless 中,如何在另一个方法中使用 Record.updateWith?

问题描述

从我在网上阅读的内容来看,无形的 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,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 完全符合此条件。所以我的问题是:

  • 如何指示updateWith的类型召唤师使用lemma1? (是用宏写的)

  • 如果这是不可能的,我还有哪些其他选项可以在方法中实现正确的更新?

非常感谢您的帮助

解决方法

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

不,没有。 partition by key1,key2Selector[HH,k.T] 是不同的类型。 Selector[HH,k.value.type]k.value.type 的子类型。 k.T 是不变的。

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

Selector

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