让我们说我有一个特质
sealed trait Expr[-InT, +OutT] {
def apply(lhs: InT): OutT
}
我想在And
中创建一个子类型InT
逆变。我必须实现它(1):
type BExpr[-InT] = Expr[InT, Boolean]
final case class And[-InT](exp: BExpr[InT], exps: BExpr[InT]*) extends BExpr[InT] {
def apply(lhs: InT) = exps.foldLeft(exp.apply(lhs))(_ & _(lhs))
}
或者以下是否足够(2)?
type BExpr[InT] = Expr[InT, Boolean]
final case class And[InT](exp: BExpr[InT], exps: BExpr[InT]*) extends BExpr[InT] {
def apply(lhs: InT) = exps.foldLeft(exp.apply(lhs))(_ & _(lhs))
}
由于
答案 0 :(得分:3)
好吧,让我们做一点测试。
scala> trait A[+T]
defined trait A
scala> trait B[T] extends A[T]
defined trait B
scala> def b1: B[String] = ???
b1: B[String]
scala> def b2: B[AnyRef] = b1
<console>:13: error: type mismatch;
found : B[String]
required: B[AnyRef]
Note: String <: AnyRef, but trait B is invariant in type T.
You may wish to define T as +T instead. (SLS 4.5)
def b2: B[AnyRef] = b1
^
scala> def a: A[AnyRef] = b1
a: A[AnyRef]
scala> trait B[+T] extends A[T]
defined trait B
scala> def b3: B[String] = ???
b3: B[String]
scala> def b4: B[AnyRef] = b3
b4: B[AnyRef]
所以是的它确实有所作为。如果您想将您的子类型公开给世界,而不是将其作为私有内部实现,那么添加适当的方差注释可能更好。