I have a class defined like this:
implicit class TraversableLikeView[+A, +Repr, Raw](self: Raw)(implicit cast: Raw => TraversableLike[A,Repr]) {
def filterByType[B, That](implicit bf: CanBuildFrom[Repr, B, That]): That = {
val result = cast(self).flatMap{
case tt: B => Some(tt)
case _ => None
}(bf)
result
}
}
When calling it on TraversableLikeView("abc" :: "def" :: Nil)
:
I want type parameter B
to be specified, and type parameter That
to be automatically inferred from predefined implicits. So I call the function like this:
TraversableLikeView("abc" :: "def" :: Nil).filterByType[String, _].foreach{...}
However, the compiler gave me this error:
Error:(38, 56) unbound wildcard type
....filterByType[String, _].foreach{...
^
Why scala is unable to infer this type parameter? What should I do to fix it?
UPDATE: The closest thing I can get is like the following:
implicit class TraversableLikeView[A, Repr, Raw <% TraversableLike[A, Repr]](self: Raw) {
def filterByType[B] = new FilterByType[B]
class FilterByType[B] {
def apply[That](implicit bf: CanBuildFrom[Repr, B, That]): That = {
val result = self.flatMap{
case tt: B => Some(tt)
case _ => None
}(bf)
result
}
}
}
test("1") {
val res: Seq[String] = Seq("abc", "def").filterByType[String].apply
println(res)
val res2: Array[String] = Array("abc", "def").filterByType[String].apply
println(res2)
val res3: Set[String] = Set("abc", "def").filterByType[String].apply
println(res3)
}
However the compiler seems to fail on finding the evidence (which shouldn't even be needed):
Error:(38, 33) value filterByType is not a member of Array[com.tribbloids.spookystuff.pages.PageLike]
val unfetched = pageLikes.filterByType[Unfetched].head
^
If I drop the view bound it will work perfectly (of course except on Array[String]), but I'm kind of surprised to see that it take such circumvention to implemennt a simple thing in scala.