First for a literal answer. Note that most parameters of type T not used. You can use this T to make your function match any element of type Some[T] :
trait folderLP extends Poly2 { implicit def default[T, L <: HList] = at[T, L]((_, acc) => acc) } object folder extends folderLP { implicit def some[T, L <: HList] = at[Some[T], L]((t, acc) => t.get :: acc) }
Note that you don't even need the none case if you switch the order of the arguments to default .
Also note that you probably want to use the following definition of filtered :
val filtered = test.foldRight(HNil: HNil)(folder)
This will have HNil statically injected as HNil instead of HList , which will be useful for almost everything you want to do along the line, for example try filtered.length on your original version and then on that.
You really don't need a fold for this operation, although -a flatMap will do:
trait filterLP extends Poly1 { implicit def any[T] = at[T](_ => HNil) } object filter extends filterLP { implicit def some[T] = at[Some[T]](_.get :: HNil) }
And then:
val filtered = test.flatMap(filter)
Finally, it is worth noting that this will only work on HList , where the elements none and Some statically typed as none and Some -a Some[A] , for example, statically typed as a Option[A] will be filtered. This makes it ridiculous (at least I donβt see any practical use), but in fact you canβt perform this type of level filter in any way if at compile time you donβt know whether Option will be empty or not.
source share