The easiest way is to use a fold. First we need a polymorphic function that will add each element to the battery if it is of the desired type ( String => A for some A ) and ignores it otherwise:
trait ignore extends Poly2 { implicit def default[A, L <: HList] = at[A, L]((_, l) => l) } object keepStringFunc extends ignore { implicit def stringFunc[A, L <: HList] = at[String => A, L](_ :: _) }
Now the following will give the result that you want in both versions 1.2.4 and 2.0.0-M1:
val filtered = hflist.foldRight(HNil)(keepStringFunc)
You can also write your own class type in the Filter , FilterAux (or Filter.Aux ) model, etc. - and it will be a good exercise if you are trying to find Shapeless-but foldRight much easier.
Update: actually, what it costs for is a slightly more concise way to do this with flatMap :
trait skip extends Poly1 { implicit def default[A] = at[A](_ => HNil) } object grabStringFunc extends skip { implicit def stringFunc[A] = at[String => A](_ :: HNil) } val filtered = hflist flatMap grabStringFunc
I personally find the foldRight version more obvious, but this one is pretty elegant too.
In response to your comment: you can make the solution more like the following:
trait skip extends Poly1 { implicit def default[A] = at[A](_ => HNil) } trait grabFuncFrom[T] extends skip { implicit def stringFunc[A] = at[T => A](_ :: HNil) } object grabStringFunc extends grabFuncFrom[String] val filtered = hflist flatMap grabStringFunc
But you still need the last step, in which you create a function of a higher rank as an object (see, for example, this answer , and Miles will comment on this to discuss this issue).