在 class 中使用 ReplaceAt
use ReplaceAt inside a class
我正在为 Shapeless HList 构建一个包装器,我想使用 updatedAt
函数来更新 HList 中的值,但我似乎无法正确理解隐式。这是我认为最接近可行解决方案的两个版本:
class Data[L <: HList](val hl: L) {
def updatedAtV1[V](n : Nat, value : V)(implicit
replacer : ReplaceAt[L, n.N, V]) : replacer.Out = replacer(hl, value)
def updatedAtV2[V, Out <: HList](n : Nat, value : V)(implicit
replacer : ReplaceAt.Aux[L, n.N, V, (V, Out)]) : Out = replacer(hl, value)._2
}
V1
编译,但是因为它 returns 一个 Tuple
我无法将它强制为 Tuple
类型所以我无法得到 replacer(hl, value)._2
元素。在 V2
中,编译器无法解析 Out
类型。
请注意 V2
工作正常,如果该值与它替换的类型相同,但如果它是不同的类型则失败。
由于这个隐含的原因,它不适用于不同的类型:
ReplaceAt.Aux[L, n.N, V, (V, Out)]
你说你想在 n
处放置一个 V
类型的值,然后从 HList 中取回 V
。您可以通过引入额外的类型参数来修复它:
def updatedAtV3[V, W, Out <: HList](n : Nat, value : V)(implicit
replacer : ReplaceAt.Aux[L, n.N, V, (W, Out)]) : Out = replacer(hl, value)._2
那里 W
- 列表中已经存在的元素 - 可以是任何东西(它将从隐式参数中推断出来),所以一切正常:
new Data(1 :: HNil).updatedAtV3(0, 42) == 42 :: HNil
new Data(1 :: HNil).updatedAtV3(0, "foo") == "foo" :: HNil
我正在为 Shapeless HList 构建一个包装器,我想使用 updatedAt
函数来更新 HList 中的值,但我似乎无法正确理解隐式。这是我认为最接近可行解决方案的两个版本:
class Data[L <: HList](val hl: L) {
def updatedAtV1[V](n : Nat, value : V)(implicit
replacer : ReplaceAt[L, n.N, V]) : replacer.Out = replacer(hl, value)
def updatedAtV2[V, Out <: HList](n : Nat, value : V)(implicit
replacer : ReplaceAt.Aux[L, n.N, V, (V, Out)]) : Out = replacer(hl, value)._2
}
V1
编译,但是因为它 returns 一个 Tuple
我无法将它强制为 Tuple
类型所以我无法得到 replacer(hl, value)._2
元素。在 V2
中,编译器无法解析 Out
类型。
请注意 V2
工作正常,如果该值与它替换的类型相同,但如果它是不同的类型则失败。
由于这个隐含的原因,它不适用于不同的类型:
ReplaceAt.Aux[L, n.N, V, (V, Out)]
你说你想在 n
处放置一个 V
类型的值,然后从 HList 中取回 V
。您可以通过引入额外的类型参数来修复它:
def updatedAtV3[V, W, Out <: HList](n : Nat, value : V)(implicit
replacer : ReplaceAt.Aux[L, n.N, V, (W, Out)]) : Out = replacer(hl, value)._2
那里 W
- 列表中已经存在的元素 - 可以是任何东西(它将从隐式参数中推断出来),所以一切正常:
new Data(1 :: HNil).updatedAtV3(0, 42) == 42 :: HNil
new Data(1 :: HNil).updatedAtV3(0, "foo") == "foo" :: HNil