From what I have read online, the shapeless Record.updateWith seems to be the only way to update both the value & type of a Record entry. So I gave it a try:
import shapeless.syntax.singleton.mkSingletonOps
import shapeless.record._
val existing = ("i" ->> 3.0) :: ("j" ->> "Abc") :: HNil
val uu = existing.updateWith("i")(_ => 123)
It worked! the output is 123 :: Abc :: HNil
, however I encounter a different problem: I cannot call this function inside another function, namely, it cannot use typeclasses in scope:
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
}
The latest compiler (2.13.4) gave the following error information:
[Error] ... : Unable to resolve implicit value of type shapeless.ops.record.Selector[HH,Witness.this.value.type]
one error found
Despite that lemma1
totally qualifies this condition. So my questions are:
How do I instruct the type class summoner of
updateWith
to uselemma1
? (it is written in macro)If this is not possible, what are my other options to implement a proper update in a method?
Thanks a lot for your help
No, it doesn't.
Selector[HH, k.T]
andSelector[HH, k.value.type]
are different types.k.value.type
is a subtype ofk.T
.Selector
is invariant.I already advised you to use type classes rather than extension methods
or