使用 Scala 抽象类型的奇怪的重复模板模式约束
Curiously recurring template pattern constraints with Scala abstract types
我有一个 Scala 编译器错误难题,我想不通。由于此处未给出的原因,我需要使用 curiously recurring template pattern 声明我的 类。我的一些 类 需要包含其他作为参数。例如,我的代码的精简版本如下所示:
trait Container[C <: Container[C]] {
def stuff: C
}
trait Aggregation {
def fill(x: Double): Unit
}
class Counted extends Container[Counted] {
def stuff = this
}
class Counting extends Container[Counting] with Aggregation {
def stuff = this
def fill(x: Double) { }
}
class Binned[V <: Container[V]](v: V) extends Container[Binned[V]] {
def stuff = this
def substuff = v
}
class Binning[V <: Container[V] with Aggregation](v: V) extends Container[Binning[V]] with Aggregation {
def stuff = this
def substuff = v
def fill(x: Double) { }
}
以上工作正常。现在我想从每个 -ing 添加一个抽象类型到每个 -ed:
trait Container[C <: Container[C]] {
type Ed <: Container[Ed]
def stuff: C
}
trait Aggregation {
def fill(x: Double): Unit
}
class Counted extends Container[Counted] {
type Ed = Counted
def stuff = this
}
class Counting extends Container[Counting] with Aggregation {
type Ed = Counted
def stuff = this
def fill(x: Double) { }
}
class Binned[V <: Container[V]](v: V) extends Container[Binned[V]] {
type Ed = Binned[V]
def stuff = this
def substuff = v
}
class Binning[V <: Container[V] with Aggregation](v: V) extends Container[Binning[V]] with Aggregation {
type Ed = Binned[V#Ed]
def stuff = this
def substuff = v
def fill(x: Double) { }
}
而且编译器还好意思告诉我
<console>:34: error: type arguments [V#Ed] do not conform to class Binned's type parameter bounds [V <: Container[V]]
type Ed = Binned[V#Ed]
当 Ed
对所有 Containers
来说显然是 <: Container[Ed]
。
严格来说,只有 Containers with Aggregation
才需要输入 Ed
,如果我把它移到那里,我会得到同样的错误。
有人知道我如何向编译器说明我的意图吗?
class Binning[V <: Container[V] with Aggregation](val v: V) extends Container[Binning[V]] with Aggregation {
type Ed = Binned[v.Ed]
def stuff = this
def substuff = v
def fill(x: Double) { }
}
有效。但在我看来你的版本也应该编译。
我有一个 Scala 编译器错误难题,我想不通。由于此处未给出的原因,我需要使用 curiously recurring template pattern 声明我的 类。我的一些 类 需要包含其他作为参数。例如,我的代码的精简版本如下所示:
trait Container[C <: Container[C]] {
def stuff: C
}
trait Aggregation {
def fill(x: Double): Unit
}
class Counted extends Container[Counted] {
def stuff = this
}
class Counting extends Container[Counting] with Aggregation {
def stuff = this
def fill(x: Double) { }
}
class Binned[V <: Container[V]](v: V) extends Container[Binned[V]] {
def stuff = this
def substuff = v
}
class Binning[V <: Container[V] with Aggregation](v: V) extends Container[Binning[V]] with Aggregation {
def stuff = this
def substuff = v
def fill(x: Double) { }
}
以上工作正常。现在我想从每个 -ing 添加一个抽象类型到每个 -ed:
trait Container[C <: Container[C]] {
type Ed <: Container[Ed]
def stuff: C
}
trait Aggregation {
def fill(x: Double): Unit
}
class Counted extends Container[Counted] {
type Ed = Counted
def stuff = this
}
class Counting extends Container[Counting] with Aggregation {
type Ed = Counted
def stuff = this
def fill(x: Double) { }
}
class Binned[V <: Container[V]](v: V) extends Container[Binned[V]] {
type Ed = Binned[V]
def stuff = this
def substuff = v
}
class Binning[V <: Container[V] with Aggregation](v: V) extends Container[Binning[V]] with Aggregation {
type Ed = Binned[V#Ed]
def stuff = this
def substuff = v
def fill(x: Double) { }
}
而且编译器还好意思告诉我
<console>:34: error: type arguments [V#Ed] do not conform to class Binned's type parameter bounds [V <: Container[V]]
type Ed = Binned[V#Ed]
当 Ed
对所有 Containers
来说显然是 <: Container[Ed]
。
严格来说,只有 Containers with Aggregation
才需要输入 Ed
,如果我把它移到那里,我会得到同样的错误。
有人知道我如何向编译器说明我的意图吗?
class Binning[V <: Container[V] with Aggregation](val v: V) extends Container[Binning[V]] with Aggregation {
type Ed = Binned[v.Ed]
def stuff = this
def substuff = v
def fill(x: Double) { }
}
有效。但在我看来你的版本也应该编译。