ava*_*gen 2 sorting types scala
我有一个简单的特性,要求实现有一个quality(x:A)我想要返回的方法Ordered[B].换句话说,quality转换A为Ordered[B].这样我可以比较B.
我有以下基本代码:
trait Foo[A] {
    def quality[B](x:A):Ordered[B]
    def baz(x1:A, x2:A) = {
       // some algorithm work here, and then
       if (quality(x1) > quality(x2)) {
           // some stuff
       }
}
我想实现如下:
class FooImpl extends Foo[Bar] {
    def quality(x:Bar):Double = {
       someDifficultQualityCalculationWhichReturnsADouble
    }
}
我认为这可以工作,因为如果我是正确的,Double隐式转换为RichDouble实现Ordered[Double].
但是在特征>的baz方法中它给了我一个quality(x2)说明的错误:Type mismatch, expected Nothing, actual Ordered[Nothing]
我不明白这一点,因为,来自C#,我发现它可以与返回类似的东西相比IEnumerable<A>,然后使用一个很好的扩展方法IEnumerable.
我在这里错过了什么?我想要的特性是在trait中定义一个复杂的算法,但是关键函数需要由实现trait的类来定义.需要使用这些函数来计算品质因数.这可以是一种Double,Int或者说是什么,但它也可以是更复杂的东西.我可以重写它总是返回它,这Double当然是可能的,但我希望特性尽可能通用,因为我希望它描述行为而不是实现.我想到了类的A实现,Ordered[A]但这似乎也很奇怪,因为它不是这个类的"目的"进行比较.
使用Ordering[A]你可以比较As而无需A实现Ordered[A].
我们可以通过添加参数来请求Ordering[A]存在:bazimplicit
trait Foo[A] {
  def baz(x1:A, x2:A)(implicit ord: Ordering[A]) = 
   if (ord.gt(x1, x2)) "first is bigger"
   else "first is smaller or equal"
}
让我们在其伴随对象中创建一个Personcase类Ordering.
case class Person(name: String, age: Int)
object Person {
  implicit val orderByAge = Ordering.by[Person, Int](_.age)
}
我们现在可以使用Foo[Person].baz因为Ordering[Person]存在:
val (alice, bob) = (Person("Alice", 50), Person("Bob", 40))
val foo = new Foo[Person] {}
foo.baz(alice, bob)
// String = first is bigger
// using an explicit ordering 
foor.baz(alice, bob)(Ordering.by[Person, String](_.name))
// String = first is smaller or equal
与我Persons按年龄Ordering[A]进行比较的方式相同,您可以A根据质量函数创建一个比较您的方式.