Search code examples
scalashapeless

How to convert a generic HList to a List


I have these:

trait A[T]
class X
class Y

object B {
   def method[H :< HList](h: H) = h.toList[A[_]]
}

Parameter h of method will always be a HList of A[T], like new A[X] :: new A[Y] :: HNil.

I would like to convert the HList to a List[A[_]].

How can I get this with generic code, because trait HList doesn't have the toList method()?


Solution

  • The compiler error should tell you something about wanting an implicit value of type shapeless.ops.hlist.ToList[H, A[_]]. You can provide one of these by adding an implicit argument list to your method signature:

    object B {
      def method[H <: HList](h: H)(implicit ev: ToList[H, A[_]]) = h.toList[A[_]]
    }
    

    Now you can write the following:

    val someAs = new A[Int] {} :: new A[String] {} :: HNil
    

    And then:

    scala> B.method(someAs)
    res0: List[A[_]] = List($anon$1@5dd508ef, $anon$2@4d3db309)
    

    Almost every operation on an HList will require this kind of implicit evidence.