Reputation: 5220
I have created a wrapper on top on HList
that can append an HLists
. It is defined as follows:
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))
}
It used like this:
case class CC(i: Int, ii: Int)
val cc = CC(100, 1000)
val hl = HListWrapper(cc)
hl.append('iii, 10000)
But when I try to put the HListWrapper
inside another function to capture the type of Out
, the compiler cannot seem to resolve the final type of the transformation (fails with type mismatch error):
def cctohlist[Out <: HList]: CC => HListWrapper[Out] = {
m => {
val hl = HListWrapper(m)
hl.append('iii, 10000)
}
}
The primary reason to create the cctohlist
method is to get the type of the HList
after append. Is this possible to achieve?
Upvotes: 0
Views: 113
Reputation: 51723
The following code works:
def cctohlist: CC => HListWrapper[Record.`'i -> Int, 'ii -> Int, 'iii -> Int`.T] = {
m => {
val hl = HListWrapper(m)
hl.append('iii, 10000)
}
}
When you write
def cctohlist[Out <: HList]: CC => HListWrapper[Out] = ???
this means I can apply cctohlist[Int :: String :: Boolean :: HNil]
and have CC => HListWrapper[Int :: String :: Boolean :: HNil]
or I can apply cctohlist[AnyVal :: AnyRef :: Any :: HNil]
and have CC => HListWrapper[AnyVal :: AnyRef :: Any :: HNil]
etc. This is obviously not the case.
This is generic one:
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)
Upvotes: 1