HList 转换 Out 类型
HList transformation Out type
我在 HList
上创建了一个可以附加 HLists
的包装器。定义如下:
class HListWrapper[L <: HList](val hl: L) {
def append[V, Out <: HList](k: Witness, v: V)(implicit updater: Updater.Aux[L, FieldType[k.T, V], Out],
lk: LacksKey[L, k.T]): HListWrapper[Out] = {
new HListWrapper(updater(hl, field[k.T](v)))
}
}
object HListWrapper {
def apply[P <: Product, L <: HList](p: P)(implicit gen: LabelledGeneric.Aux[P, L]) =
new HListWrapper(gen.to(p))
}
它是这样使用的:
case class CC(i: Int, ii: Int)
val cc = CC(100, 1000)
val hl = HListWrapper(cc)
hl.append('iii, 10000)
但是当我尝试将 HListWrapper
放入另一个函数中以捕获 Out
的类型时,编译器似乎无法解析转换的最终类型(因类型不匹配错误而失败) :
def cctohlist[Out <: HList]: CC => HListWrapper[Out] = {
m => {
val hl = HListWrapper(m)
hl.append('iii, 10000)
}
}
创建cctohlist
方法的主要原因是在附加后获取HList
的类型。这有可能实现吗?
以下代码有效:
def cctohlist: CC => HListWrapper[Record.`'i -> Int, 'ii -> Int, 'iii -> Int`.T] = {
m => {
val hl = HListWrapper(m)
hl.append('iii, 10000)
}
}
写的时候
def cctohlist[Out <: HList]: CC => HListWrapper[Out] = ???
这意味着我可以申请 cctohlist[Int :: String :: Boolean :: HNil]
并获得 CC => HListWrapper[Int :: String :: Boolean :: HNil]
或者我可以申请 cctohlist[AnyVal :: AnyRef :: Any :: HNil]
并获得 CC => HListWrapper[AnyVal :: AnyRef :: Any :: HNil]
等等。这显然不是这种情况。
这是通用的:
def cctohlist[P <: Product, L <: HList, Out <: HList](m: P)(implicit
gen: LabelledGeneric.Aux[P, L],
updater: Updater.Aux[L, FieldType[Witness.`'iii`.T, Int], Out],
lk: LacksKey[L, Witness.`'iii`.T]
): HListWrapper[Out] = {
val hl = HListWrapper(m)
hl.append('iii, 10000)
}
cctohlist(cc)
我在 HList
上创建了一个可以附加 HLists
的包装器。定义如下:
class HListWrapper[L <: HList](val hl: L) {
def append[V, Out <: HList](k: Witness, v: V)(implicit updater: Updater.Aux[L, FieldType[k.T, V], Out],
lk: LacksKey[L, k.T]): HListWrapper[Out] = {
new HListWrapper(updater(hl, field[k.T](v)))
}
}
object HListWrapper {
def apply[P <: Product, L <: HList](p: P)(implicit gen: LabelledGeneric.Aux[P, L]) =
new HListWrapper(gen.to(p))
}
它是这样使用的:
case class CC(i: Int, ii: Int)
val cc = CC(100, 1000)
val hl = HListWrapper(cc)
hl.append('iii, 10000)
但是当我尝试将 HListWrapper
放入另一个函数中以捕获 Out
的类型时,编译器似乎无法解析转换的最终类型(因类型不匹配错误而失败) :
def cctohlist[Out <: HList]: CC => HListWrapper[Out] = {
m => {
val hl = HListWrapper(m)
hl.append('iii, 10000)
}
}
创建cctohlist
方法的主要原因是在附加后获取HList
的类型。这有可能实现吗?
以下代码有效:
def cctohlist: CC => HListWrapper[Record.`'i -> Int, 'ii -> Int, 'iii -> Int`.T] = {
m => {
val hl = HListWrapper(m)
hl.append('iii, 10000)
}
}
写的时候
def cctohlist[Out <: HList]: CC => HListWrapper[Out] = ???
这意味着我可以申请 cctohlist[Int :: String :: Boolean :: HNil]
并获得 CC => HListWrapper[Int :: String :: Boolean :: HNil]
或者我可以申请 cctohlist[AnyVal :: AnyRef :: Any :: HNil]
并获得 CC => HListWrapper[AnyVal :: AnyRef :: Any :: HNil]
等等。这显然不是这种情况。
这是通用的:
def cctohlist[P <: Product, L <: HList, Out <: HList](m: P)(implicit
gen: LabelledGeneric.Aux[P, L],
updater: Updater.Aux[L, FieldType[Witness.`'iii`.T, Int], Out],
lk: LacksKey[L, Witness.`'iii`.T]
): HListWrapper[Out] = {
val hl = HListWrapper(m)
hl.append('iii, 10000)
}
cctohlist(cc)