Scala按类型参数和返回构造筛选返回类型和类型构造函数

Scala按类型参数和返回构造筛选返回类型和类型构造函数,scala,Scala,我有以下工作代码 case class FilterType[A](t: GenTraversable[A]) { def filterType[B](implicit tag: ClassTag[B]): GenTraversable[B] = t.flatMap { case element: B => Some(element) case _ => None } } 有了这个定义,我可以按预期过滤以下内容 trait Demo cas

我有以下工作代码

case class FilterType[A](t: GenTraversable[A]) {
  def filterType[B](implicit tag: ClassTag[B]): GenTraversable[B] = t.flatMap {
    case element: B => Some(element)
    case _          => None
  }
}
有了这个定义,我可以按预期过滤以下内容

trait Demo
case class Demo1(a: String) extends Demo
case class Demo2(a: Int)    extends Demo

val input: Seq[Demo]              = Seq(Demo1("hello"), Demo2(2))
val output: GenTraversable[Demo1] = FilterType(input).filterType[Demo1]
我想对此进行改进,并将类型构造函数作为一个参数,这样我就可以返回与
输入相同的类型,而不是返回
GenTraversable
(在本例中是a
Seq
)。我的尝试如下

case class FilterType2[T[_]: GenTraversable, A](t: T[A]) {
  def filterType[B](implicit tag: ClassTag[B]): T[B] = t.flatMap {
    case element: B => Some(element)
    case _          => None
  }
}
但是,我得到了以下编译错误:

Error 1: type T takes type parameters
Error 2: value flatMap is not a member of type parameter T[A]
对于第一个错误:


gentraVersable
不是上下文/类型类。您需要的是
gentraversable
的子类,而不是它的上下文,因此应该使用
None
}
}

完整代码:

GentraVersable
不是一个类型类,如果你想使用这种方法,你可能会对cats
Functor
感兴趣,否则请看:(并调整代码或google以适应
2.12-
方法)-顺便说一句,注意,由于类型擦除,按类过滤可能并不总是像预期的那样工作-最后,使用
collect
比使用
flatMap
更简单。使用
collect
比使用
flatMap
更好。你说得对。
case class FilterType[T[A] <: GenTraversableLike[A, T[A]], A](t: T[A]) {
  def filterType[B](implicit tag: ClassTag[B], bf: CanBuildFrom[T[A], B, T[B]]): T[B] = t.flatMap {
    case element: B => Some(element)
    case _          => None
  }
}