Scala:trait中的抽象比较方法
Scala: abstract comparison method in trait
我有一个具有大小比较功能的特征,我想在子类中实现:
trait A {
def isLessThan(that: A): Boolean
...
}
class SubOfA() extends A {
...
override def isLessThan(that: SubOfA): Boolean = {
this.size < that.size
}
...
}
但是,该方法不是有效的覆盖,因为参数类型是 SubOfA
而不是 A
。
我也试过将参数类型设置为 this.type
,但是当我从抽象设置中调用方法时,我不能使用类型为 A
的对象作为参数:
...
(foo: A, bar: A) => foo.isLessThan(bar)
这需要类型 foo.type
而不是 A
,它们是相同的,但我认为编译器还不知道。
关于如何让这样的东西发挥作用有什么想法吗?我到处寻找答案,但找不到任何东西。也许我不知道问什么才是正确的问题。
您可以使用以下方法修复第一种方法:
class SubOfA() extends A {
override def isLessThan(that: A): Boolean = that match {
case that : subOfA => this.size < that.size
case _ => throw new UnsupportedOperationException("Wrong comparison") //or whatever behaviour deemed suitabe here
}
}
您可以使用F-Bounded
多态性 (这将解决Java), or Typeclasses
多态性 (Haskell).
我个人的偏好是使用类型类,因为它更可扩展、更易于维护且类型更安全 - Here 更 objective Rob Norris 的比较。
F-有界。
trait Comparable[A <: Comparable[A]] { this: A =>
def isLessThan(that: A): Boolean
}
class SubOfComparable extends Comparable[SubOfComparable] {
val size: Int = ???
override final def isLessThan(that: SubOfComparable): Boolean =
this.size < that.size
}
类型类。
trait Comparator[T] {
def isLessThan(a: T, b: T): Boolean
}
object syntax {
object comparator {
implicit final class ComparatorOps[T](val self: T) extends AnyVal {
final def < (that: T)(implicit C: Comparator[T]): Boolean =
C.isLessThan(self, that)
}
}
}
class Sub {
final val size: Int = ???
}
object Sub {
implicit val SubComparator: Comparator[Sub] = new Comparator[Sub] {
override final def isLessThan(a: Sub, b: Sub): Boolean =
a.size < b.size
}
}
import syntax.comparator._
val a = new Sub(...)
val b = new Sub(...)
a < b
我有一个具有大小比较功能的特征,我想在子类中实现:
trait A {
def isLessThan(that: A): Boolean
...
}
class SubOfA() extends A {
...
override def isLessThan(that: SubOfA): Boolean = {
this.size < that.size
}
...
}
但是,该方法不是有效的覆盖,因为参数类型是 SubOfA
而不是 A
。
我也试过将参数类型设置为 this.type
,但是当我从抽象设置中调用方法时,我不能使用类型为 A
的对象作为参数:
...
(foo: A, bar: A) => foo.isLessThan(bar)
这需要类型 foo.type
而不是 A
,它们是相同的,但我认为编译器还不知道。
关于如何让这样的东西发挥作用有什么想法吗?我到处寻找答案,但找不到任何东西。也许我不知道问什么才是正确的问题。
您可以使用以下方法修复第一种方法:
class SubOfA() extends A {
override def isLessThan(that: A): Boolean = that match {
case that : subOfA => this.size < that.size
case _ => throw new UnsupportedOperationException("Wrong comparison") //or whatever behaviour deemed suitabe here
}
}
您可以使用F-Bounded
多态性 (这将解决Java), or Typeclasses
多态性 (Haskell).
我个人的偏好是使用类型类,因为它更可扩展、更易于维护且类型更安全 - Here 更 objective Rob Norris 的比较。
F-有界。
trait Comparable[A <: Comparable[A]] { this: A =>
def isLessThan(that: A): Boolean
}
class SubOfComparable extends Comparable[SubOfComparable] {
val size: Int = ???
override final def isLessThan(that: SubOfComparable): Boolean =
this.size < that.size
}
类型类。
trait Comparator[T] {
def isLessThan(a: T, b: T): Boolean
}
object syntax {
object comparator {
implicit final class ComparatorOps[T](val self: T) extends AnyVal {
final def < (that: T)(implicit C: Comparator[T]): Boolean =
C.isLessThan(self, that)
}
}
}
class Sub {
final val size: Int = ???
}
object Sub {
implicit val SubComparator: Comparator[Sub] = new Comparator[Sub] {
override final def isLessThan(a: Sub, b: Sub): Boolean =
a.size < b.size
}
}
import syntax.comparator._
val a = new Sub(...)
val b = new Sub(...)
a < b