使用 ADT 时,特征 Enumeratee 在类型 From 上是不变的

trait Enumeratee is invariant in type From when using ADT

我正在尝试组合一个 Enumeratee.grouped 和一个 Enumeratee.filter 来创建一个新的枚举对象,但是我 运行 遇到了差异问题。我的 enumeratee 的输入和输出类型是 ADT,我收到以下错误。

<console>:24: error: type mismatch;
 found   : play.api.libs.iteratee.Enumeratee[OutputType,OutputType]
 required: play.api.libs.iteratee.Enumeratee[Product with Serializable with OutputType,OutputType]
Note: OutputType >: Product with Serializable with OutputType, but trait Enumeratee is invariant in type From.
You may wish to define From as -From instead. (SLS 4.5)

我在这里用一个较小的例子重新创建了我的问题(我知道这个例子可以重写为 Enumeratee.collect 但是,除非有一种方法可以组合 Enumeratee.groupedEnumeratee.filter 这对我没有帮助。)

import play.api.libs.iteratee.Enumeratee
import scala.concurrent.ExecutionContext.Implicits.global

sealed abstract class InputType
case class InputA(counter: Int) extends InputType
case object InputB extends InputType

sealed abstract class OutputType
case class OutputA(msg: String) extends OutputType
case object OutputB extends OutputType

val e: Enumeratee[InputType, OutputType] = Enumeratee.map[InputType] { 
  case InputA(counter) => OutputA(counter.toString)
  case InputB => OutputB
} compose Enumeratee.filter[OutputType] { 
  case OutputA("4") => false
  case _ => true
}

我无法按照编译器错误提示将 Enumeratee 上的 From 类型重新定义为 -From,因为它是一个播放库。在编写 enumeratees 时不能使用 ADT 是库的限制吗?或者对于这个用例是否有更好的方法(在某处放置 ClassTag,以另一种方式编写此功能,等等...)?

我找到了一个看起来不错的解决方案。如果将 Enumeratee.map[InputType] 更改为 Enumeratee.map[InputType].apply[OutputType],推理器将获得不变类型并且编译得很好。

val e: Enumeratee[InputType, OutputType] = Enumeratee.map[InputType].apply[OutputType] { 
  case InputA(counter) => OutputA(counter.toString)
  case InputB => OutputB
}