Reputation: 25
I am new to shapeless (and still low level in the learning curve of scala...) and i have some hard time with shapeless
import shapeless._
case class FooBar[T](foo: String, bar: T)
val hl = 0 :: FooBar("A", "one") :: FooBar("B", 1) :: "0" :: FooBar("C", "two") :: HNil
val l = hl.filter[FooBar[String]].toList
println(l) //List(FooBar(A,one), FooBar(C,two))
It works fine
Next step, i want to put that in function, something like
def filter[T](hl: HList): List[FooBar[T]] = ???
so i can simplify calling to
filter[String](hl)
filter[Int](hl)
naively i tested
def filter[T](hl: HList): List[FooBar[T]] = {
hl.filter[FooBar[T]].toList
}
which give
could not find implicit value for parameter partition: shapeless.ops.hlist.Partition[shapeless.HList,FooBar[T]]
after some tries playing with implicit, i still have not found the correct way to do that
Do you have any idea ?
Thank you !
Upvotes: 0
Views: 312
Reputation: 51658
If you lack some implicits then in your method you should suppose they are provided. Saying that an argument of the method is of type just HList
(and not some specific L <: HList
) is too rough.
Since probably you would like to specify T
and not specify L
(expecting that L
will be inferred) try a type class + extension method
import shapeless._
import shapeless.ops.hlist.{Partition, ToTraversable}
case class FooBar[T](foo: String, bar: T)
val hl = 0 :: FooBar("A", "one") :: FooBar("B", 1) :: "0" :: FooBar("C", "two") :: HNil
trait FilterFooBar[L <: HList, T] {
def apply(l: L): List[FooBar[T]]
}
object FilterFooBar {
implicit def mkFilterFooBar[L <: HList, T, Prefix <: HList, Suffix <: HList](implicit
partition: Partition.Aux[L, FooBar[T], Prefix, Suffix],
toTraversable: ToTraversable.Aux[Prefix, List, FooBar[T]]
): FilterFooBar[L, T] = _.filter.toList
}
implicit class FilterFooBarOp[L <: HList](l: L) {
def filterFooBar[T](implicit filterFooBarInstance: FilterFooBar[L, T]): List[FooBar[T]] =
filterFooBarInstance(l)
}
println(hl.filterFooBar[String]) // List(FooBar(A,one), FooBar(C,two))
println(hl.filterFooBar[Int]) // List(FooBar(B,1))
Upvotes: 1