jamborta
jamborta

Reputation: 5220

HList transformation Out type

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

Answers (1)

Dmytro Mitin
Dmytro Mitin

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

Related Questions