我正在为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
编译,但因为它返回Tuple
我无法将其强制转换为Tuple
类型,因此我无法获得replacer(hl, value)._2
元素。在V2
中,编译器无法解析Out
类型。
请注意,如果值与其替换的类型相同,则V2
可以正常工作,但如果它是不同的类型则会失败。
答案 0 :(得分:2)
由于隐含的原因,它不适用于不同的类型:
ReplaceAt.Aux[L, n.N, V, (V, Out)]
您已告知要在V
处放置n
类型的值,并将V
退出HList。您可以通过引入额外的类型参数来修复它:
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