我试图编写一个附加一个HList的函数,我发现Updater是最接近我想要的:
def appender[L <: HList, V, Out <: HList](hl: L, k: Witness, v: V)(implicit updater: Updater.Aux[L, FieldType[k.T, V], Out]) : Out = {
updater(hl, field[k.T](v))
}我有一个更新和附加一个HList的函数,但是我想禁用更新,并且只允许这个函数追加,这样:
val hl = 'field1 ->> 1 :: HNil
appender(hl, 'field2, 2) //should compile
appender(hl, 'field1, 2) //should fail目前都在编译。不管怎样,我可以用无形来表达这个约束吗?我想也许可以提出证据,证明Out类型比in类型长一个元素?
发布于 2017-09-30 20:55:39
使用shapeless.ops.record.LacksKey
def appender[L <: HList, V, Out <: HList](hl: L, k: Witness, v: V)(implicit
updater: Updater.Aux[L, FieldType[k.T, V], Out],
lk: LacksKey[L, k.T]) : Out = {
updater(hl, field[k.T](v))
}发布于 2017-09-30 23:53:20
对于后人,这里有一个答案,用你的长度检查的想法。不过,LacksKey的方式更好。而且,如果您重用一个键,但是使用另一个类型(因为类型实际上是键的一部分),Updater会创建重复的键,这意味着这个append也会这样做。
def append[
Value,
In <: HList,
Out <: HList,
InSize <: Nat,
OutSize <: Nat,
AddedNum <: Nat
](in: In, key: Witness, value: Value)(implicit
update: Updater.Aux[In, FieldType[key.T, Value], Out],
inSize: Length.Aux[In, InSize],
outSize: Length.Aux[Out, OutSize],
addedNum: ops.nat.Diff.Aux[OutSize, InSize, AddedNum], // ops.{hlist, nat}.Diff conflict
sizeRestriction: AddedNum =:= _1 // Bonus: error messages are fairly readable: "Cannot prove that AddedNum = Succ[_0]" (followed by a horrifyingly long "not enough arguments" error).
): Out = update(in, field[key.T](value))请注意,计算中的所有类型级别的值都需要是类型参数,因为您不能拥有在同一参数列表中提到其他参数的类型的参数。您需要非常小心,不要要求编译器做的比它能够处理的每一步都多。
https://stackoverflow.com/questions/46505890
复制相似问题