我正在尝试使用基于单个路径依赖类型的更简单版本替换使用2个类型参数和自我类型定义的类型。
我的问题是我无法表达相同的约束。我认为一个完整的例子将更容易理解。
class Attribute
// Test 1: Using a 2nd higher-kinded parameter and a self-type
// Advantage: Subclasses are constrained by the self-type to specify the "This" parameter correctly
// Drawback: Container1 has a 2nd type parameter and "AnyContainer1" type is really ugly
sealed trait Container1[+A <: Attribute, +This[+X <: Attribute] <: Container1[X, This]] { self: This[A] => }
class Foo[+A <: Attribute] extends Container1[A, Foo]
//class Bar[+A <: Attribute] extends Container1[A, Foo] // Won't compile :-)
object Container1 {
// This is ugly...
type AnyContainer1[+X <: Attribute] = F[X] forSome { type F[+Y <: Attribute] <: Container1[X, F] }
// type AnyContainer1[+X <: Attribute] = Container1[X, AnyContainer1] // This doesn't compile :-(
}
// Test 2: Using path-dependent types
// Advantage: Container2 has a single type parameter and AnyContainer2 is easily expressed
// Drawback: The path-dependent parameter can be overridden in a bad way
sealed trait Container2[+A <: Attribute] {
protected type This[+B <: Attribute] <: Container2[B]
// Note that I need `This` to take a generic parameter in
// order to declare methods like `def foo[T]: This[T]` in subclasses.
}
class Bar[+A <: Attribute] extends Container2[A] {
override protected type This[+X <: Attribute] = Bar[X]
}
class Baz[+A <: Attribute] extends Container2[A] {
// Will compile even though `Bar != Baz`, I'd like to enforce This = Baz somehow...
override protected type This[+X <: Attribute] = Bar[X]
}
object Container2 {
type AnyContainer2[+X <: Attribute] = Container2[Attribute] // Easy :-)
}
在使用路径依赖类型保持清洁时,是否有更好的方法来约束This
类型?使用Scala的下一个版本(现在为Dotty),存在类型将消失,并且应该用路径依赖类型替换,那么如何在没有存在类型的情况下实现它呢?