Search code examples
scalashapeless

Build Shapeless implicit in the function


I have a use case where I create an HList Record and pass it to a different function, and select an element in the function it was passed to. I couldn't find a way to make any of the following work:

Pass an HList to the function with a Witness defined in the function:

  def sel0[L <: HList](hl: L) = {
    val w = Witness('field1)
    implicit val selector = the[Selector[L, w.T]]
    selector(hl)
  }

or pass and HList and a Witness and build the Selector in the function

  def sel1[L <: HList](hl: L, w: Witness) = {
    implicit val selector = the[Selector[L, w.T]]
    selector(hl)
  }

Not even a simpler version where the implicit in contructed from the Witness before sent to the function:

  val hl = 'field1 ->> 1 :: 'field2 ->> "2" :: HNil
  val w = Witness('field1)
  val selector = the[Selector[hl.type, w.T]]

  def sel2[L <: HList](hl: L, w: Witness)(implicit selector: Selector[L, w.T]) = {
    selector(hl)
  }

  sel2(r1, w)(selector)

Any suggestion why these above don't work?


Solution

  • Use this one

    def sel0[L <: HList](hl: L)(implicit 
      selector: shapeless.ops.hlist.Selector[L, FieldType[Witness.`'field1`.T, Int]]) = 
      selector(hl)
    

    or this

    def sel0[L <: HList](hl: L)(implicit 
      selector: shapeless.ops.record.Selector[L, Witness.`'field1`.T]) = 
      selector(hl)
    

    selector(selector) is very strange.

    You don't need hl.type. It's the type of this particular hl. The correct type of hl is the type of all such hls, i.e. Record.`'field1 -> Int, 'field2 -> String`.T or FieldType[Witness.`'field1`.T, Int] :: FieldType[Witness.`'field2`.T, String] :: HNil.