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
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/

相关文章:

scala - 如何使用 Play Framework 在 Scala 中使用 WebSocket?

scala - 将所有具有特殊条件的列放在列 spark 上

scala - Spark DataFrame 将 struct<.. 包装到 struct<. 的数组中

java - 用 Maven 重命名一个 fat jar

scala - 如何将字符串映射到字符列表

scala - YARN 因超出内存限制而杀死容器

scala - Spark utf 8错误,非英文数据变成 `??????????`

scala - 了解列表[+ A]的协方差

scala - spark 是否优化应用于 RDD 的多个过滤器?

json - 如何在光滑中创建带有外键的模型?