【发布时间】:2015-10-18 08:18:46
【问题描述】:
我已经定义了两个类型类:
trait WeakOrder[-X] { self =>
def cmp(x: X, y: X): Int
def max[Y <: X](x: Y, y: Y): Y = if (cmp(x, y) >= 0) x else y
def min[Y <: X](x: Y, y: Y): Y = if (cmp(x, y) <= 0) x else y
}
trait Lattice[X] { self =>
def sup(x: X, y: X): X
def inf(x: X, y: X): X
}
我想做以下事情:
trait TotalOrder[-X] extends Lattice[X] with WeakOrder[X] { self =>
def sup(x: X, y: X): X = max(x, y)
def inf(x: X, y: X): X = min(x, y)
}
但这是不可能的,因为逆变类型 X 出现在协变位置(sup 和 inf 的返回值)。
但是,从语义上讲,这是正确的:max 和 min 带有类型签名 max[Y <: X](x: Y, y: Y): Y 编码了这样一个事实:max / min 的返回值必须是两个参数之一。
我尝试执行以下操作:
trait TotalOrder[-X] extends Lattice[X] with WeakOrder[X] { self =>
def sup[Y <: X](x: Y, y: Y): Y = max(x, y)
def inf[Y <: X](x: Y, y: Y): Y = min(x, y)
}
但是,方法def sup[Y <: X](x: Y, y: Y): Y 不能继承def sup[X](x: X, y: X): X。编译器抱怨类型签名不匹配。但是前一个(带有现场差异注释)比后一个签名施加了更强的类型限制。为什么前者不能继承后者?如何绕过TotalOrder[-X] 的逆变类型限制(语义上,总订单是逆变的)?
【问题讨论】:
标签: scala typeclass contravariance