0

私がオンラインで読んだことから、形のない Record.updateWith は、レコード エントリの値と型の両方を更新する唯一の方法のようです。だから私はそれを試してみました:


  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この状態を完全に修飾します。だから私の質問は:

  • updateWithの型クラス サモナーにを使用するように指示するにはどうすればよいlemma1ですか? (マクロで書いてあります)

  • これが不可能な場合、メソッドで適切な更新を実装するための他のオプションは何ですか?

助けてくれてどうもありがとう

4

1 に答える 1

1

それにもかかわらず、補題 1 はこの条件を完全に修飾します。

いいえ、そうではありません。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 に答える