我有以下工作代码
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
>输入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]
最佳答案
对于您的第一个错误:
GenTrasversable
不是上下文/类型类。您期待 GenTrasversable
的子类,不是它的上下文,所以你应该使用 <:
而不是:
.
对于第二个错误:
flatMap
不属于GenTrasversable
。它属于GenTraversableLike
: doc
工作代码:
您还需要CanBuildFrom
在 Scala 2.12 中用于构造通用集合。
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
}
}
完整代码:code
关于Scala 按类型参数过滤并返回构造函数返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66679646/