我在Scala中正确输入时遇到问题 - 我想做类似的事情,在类层次结构上强加Ordered,但是子类允许比较方法只使用自己类型的参数
abstract class Parent extends Ordered
class A extends Parent {
override def compare(that : A) = 1
}
class B extends Parent {
override def compare(that : B) = 1
}
以下是有效的,但是我永远被迫永远强加对Parent及其子类的类型特异性。这只是一个正确推理的噩梦。
abstract class Parent[T <: Parent[_]] extends Ordered[T]
class A extends Parent[A] {
override def compare(that : A) = 1
}
class B extends Parent[A] {
override def compare(that : B) = 1
}
是否有一种更简单的方法来命令Ordered [T]的子类上的类型?
答案 0 :(得分:2)
为什么不
abstract class Parent
class A extends Parent with Ordered[A] {...}
class B extends Parent with Ordered[B] {...}
正如其他人所指出的那样,根据你的比较标准,Parent
s序列不会被排序,因为它的子类不具有可比性。只有它的子类是Ordered
,所以在那里实现特征。
答案 1 :(得分:1)
我同意这个问题有点烦人,但如果你正在寻找的行为被允许会有点奇怪。假设你做了
trait Parent {
this: Ordered[ThisType]
}
// Does A need to be Ordered[A]?
trait A extends Parent
// Should B, C be comparable? If A is Ordered, then they
// have to be. But is this what you want?
class B extends A
class C extends A
// Now what?
class D extends B
基本上,使用继承强制这样的某些属性会有点奇怪......它可能在理论上有用,但它与继承的含义不同。相反,您可以在需要时在方法中指定Ordered
约束:
def foo[T <: Ordered[T]](x: T) = ...
或者,如果您想将Ordered
约束和其他可能的约束分组在一个通用名称下,您可以创建一个类型类型的特征:
trait Parent[A] {
val order: Ordering[A]
}
def foo[T : Parent](x: T, y: T) {
println(implicitly[Parent[T]].order.compare(x, y))
}
此解决方案的一个不幸方面是您无法指定sealed
;如果有人能解决这个问题,我会感兴趣的。否则,你可以使用依赖类型的编程语言,他们在这方面做得更好。
答案 2 :(得分:1)
答案 3 :(得分:0)
感谢这是一个非常好的见解 - 以前从未考虑过。我只是点亮这个作为解决方案,但坦率地说它看起来有点臭,它让我有点紧张。评论
abstract class Parent extends Ordered[Parent] {
override def compare(that : Parent) : Int = {
(this, that) match {
case (x : A, y : A) => x.compare(y)
case (x : B, y : B) => x.compare(y)
case _ => throw new ClassCastException
}
}
}
class A extends Parent {
def compare(that : A) = 1
}
class B extends Parent {
def compare(that : B) = 1
}