【发布时间】:2013-02-17 12:38:20
【问题描述】:
假设我们有一个具有协变和逆变类型参数的类:
sealed trait Pipe[-I,+O,+R]
// case subclasses
我们为这个类的实例定义了单子操作:
object Pipe {
def flatMap[I,O,Ri,R](p: Pipe[I,O,Ri], f: Ri => Pipe[I,O,R]): Pipe[I,O,R] =
...
}
为了能够使用 for-comprehension,我们需要 flatMap 是 trait 本身的一个方法:
sealed trait Pipe[-I,+O,+R] {
def flatMap[I,O,Ri,R](f: Ri => Pipe[I,O,R]): Pipe[I,O,R] =
Pipe.flatMap(this, f);
}
但是,这不会编译,它会失败
逆变类型
I出现在值f的类型(R) => Pipe[I,O,R1]的协变位置。
(协变类型参数也会出现类似的错误。)
我了解限制以及问题发生的原因。但是是否有一些解决方法,如何使用与上述相同语义的Pipes.flatMap 在特征上定义flatMap?也许使用一些隐式转换和/或中间构建器类?
【问题讨论】:
标签: scala monads covariance contravariance for-comprehension