There are several workarounds for parameterizing a Poly , one of which is mentioned in the other answer, although the exact implementation will not work there. Instead, you need to do this:
import shapeless._, shapeless.poly.~> val lists = List(1, 2) :: List("A", "B") :: List(1.1, 2.2) :: HNil class sss(i: Int) extends (List ~> Set) { def apply[T](l: List[T]): Set[T] = l.slice(i, i+1).toSet } object sss1 extends sss(1) lists.map(sss1)
... where the last line of compilation requires the fact that sss1 is defined as an object (and not a val ).
This approach compiles, but cannot be used in many contexts. you cannot define your sss1 (or any other) object in a method where the type hlist is shared.
Here's a slightly dirtier, but more flexible workaround I used before:
import shapeless._ val lists = List(1, 2) :: List("A", "B") :: List(1.1, 2.2) :: HNil object sss extends Poly2 { implicit def withI[T]: Case.Aux[List[T], Int, Set[T]] = at((l, i) => l.slice(i, i + 1).toSet) } lists.zipWith(lists.mapConst(1))(sss)
Now you can write a method that L <: HList generic L <: HList and slice i parameter - you just need a few implicit arguments to support the mapConst and zipWith .
None of these approaches are very elegant, and I personally try to avoid Poly most of the time, defining a class of a custom type will be almost clean and in many cases necessary.
Travis brown
source share