[英]Scala: abstract comparison method in trait
I have a trait with a size comparison function that I want to implement in a sublcass: 我有一个特征,它具有要在sublcass中实现的大小比较功能:
trait A {
def isLessThan(that: A): Boolean
...
}
class SubOfA() extends A {
...
override def isLessThan(that: SubOfA): Boolean = {
this.size < that.size
}
...
}
However, the method isn't a valid override because the argument type is SubOfA
and not A
. 但是,该方法不是有效的替代,因为参数类型是
SubOfA
而不是A
I've also tried making the argument type this.type
, but then when I am calling the method from an abstract setting I can't use an object of type A
as the argument: 我也尝试过使参数类型为
this.type
,但是当我从抽象设置中调用方法时,我不能使用A
类型的对象作为参数:
...
(foo: A, bar: A) => foo.isLessThan(bar)
This would expect type foo.type
and not A
which are the same but I don't think the compiler knows that yet. 这将期望类型
foo.type
而不是A
,它们是相同的,但是我认为编译器还不知道。
Any ideas of how I could get something like this to work? 关于如何使这种工作有效的任何想法? I've looked all over the place to find an answer to this, but can't find anything.
我到处都在寻找答案,但是什么也找不到。 Maybe I don't know what is the right question to ask.
也许我不知道问什么是正确的问题。
You can either use F-Bounded
polymorphism (which would the solution on Java ) , or Typeclasses
polymorphism (which would be the solution on Haskell ) . 您可以使用
F-Bounded
多态性 (这是Java上的解决方案) ,也可以使用Typeclasses
多态性 (这是Haskell上的解决方案) 。
My personal preference is to use typeclasses, because it is more extensible, maintainable & more typesafe - Here is more objective comparison by Rob Norris. 我个人比较喜欢使用类型类,因为它具有更好的可扩展性,可维护性和类型安全性-Rob Norris 在此进行了更为客观的比较。
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
You can fix the first method with: 您可以使用以下方法解决第一种方法:
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
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.