Из-за стирания типа чек
case s:T => ...
становится чем-то вроде
if (s.isInstanceOf[Object]) ...
, как указано в предупреждающем сообщении компилятора
warning: abstract type pattern T is unchecked since it is eliminated by erasure
list.collect({case s:T => s}).toList
Попробуйте предоставить ClassTag примерно так
import scala.reflect.ClassTag
def collect[T: ClassTag](list: Iterable[Any]): List[T] = {
list.collect({ case s: T => s }).toList
}
collect[Boolean](List(true, false, 2.0, 2, 4, 12.3))
collect[Double](List(true, false, 2.0, 2, 4, 12.3))
, который выдает
res0: List[Boolean] = List(true, false)
res1: List[Double] = List(2.0, 12.3)
, который работает из-за некоторой магии компилятора, объясненной здесь .
Вот наше собственное решение класса типов
trait Collectable[T] {
def collect(list: Iterable[Any]): List[T]
}
object Collectable {
def collect[T](list: Iterable[Any])(implicit ev: Collectable[T]): List[T] =
ev.collect(list)
implicit val booleanCollect: Collectable[Boolean] =
(list: Iterable[Any]) => list.collect({ case s: Boolean => s }).toList
implicit val doubleCollect: Collectable[Double] =
(list: Iterable[Any]) => list.collect({ case s: Double => s }).toList
}
import Collectable._
collect[Boolean](List(true, false, 2.0, 2, 4, 12.3))
collect[Double](List(true, false, 2.0, 2, 4, 12.3))
, которое выдает
res0: List[Boolean] = List(true, false)
res1: List[Double] = List(2.0, 12.3)