First, we can create Poly1 , similar to size , which we can use to map an HList to an HList from Strings .
object strings extends Poly1 { implicit def caseInt = at[Int](_.toString) implicit def caseString = at[String](identity) }
You have already used Generic[Pair] to turn Pair into an HList , but you could not display it hp , because in your funrun there is no evidence that you can display over it. We can solve this using implicit parameters.
def funRun[L <: HList, M <: HList]( p: Pair )(implicit gen: Generic.Aux[Pair, L], mapper: Mapper.Aux[strings.type, L, M] ) = gen.to(p).map(strings)
- Our first implicit parameter
gen can turn a Pair into an HList type L - Our second implicit parameter,
mapper can use our polymorphic function Strings to map an HList type L to an HList type M
Now we can use funrun to turn a Pair into an HList of Strings :
scala> funRun(Pair("abc", 12)) res1: shapeless.::[String,shapeless.::[String,shapeless.HNil]] = abc :: 12 :: HNil
But you wanted to return List[String] . To turn our HList M (display result into String ) into List[String] , we need ToTraversable , so we add a third implicit parameter:
import shapeless._, ops.hlist._ def pairToStrings[L <: HList, M <: HList]( p: Pair )(implicit gen: Generic.Aux[Pair, L], mapper: Mapper.Aux[strings.type, L, M], trav: ToTraversable.Aux[M,List,String] ): List[String] = gen.to(p).map(strings).toList
What we can use as:
scala> pairToStrings(Pair("abc", 12)) res2: List[String] = List(abc, 12)