2

我的代码:

import Ordered.orderingToOrdered
import java.util.Date

val (d1, d2) = (Option(new Date()), Option(new Date()))
d1 compare d2

-Xlog-implicits 的结果:

Information:(268, 5) math.this.Ordering.Option is not a valid implicit value for    
     scala.math.Ordering[Option[java.util.Date]] because:
     diverging implicit expansion for type scala.math.Ordering[Option[java.util.Date]]
     starting with method ordered in trait LowPriorityOrderingImplicits
        d1 compare d2
        ^

Information:(268, 5) math.this.Ordering.comparatorToOrdering is not a valid implicit      
    value for scala.math.Ordering[Option[java.util.Date]] because:
    diverging implicit expansion for type scala.math.Ordering[Option[java.util.Date]]
    starting with method ordered in trait LowPriorityOrderingImplicits
        d1 compare d2
        ^

Error:(268, 5) diverging implicit expansion for type  
    scala.math.Ordering[Option[java.util.Date]]
    starting with method ordered in trait LowPriorityOrderingImplicits
    d1 compare d2
    ^

我认为这里发生的是 Ordered 和 Ordering 之间的循环 - 隐式 Ordering[Option[Date]] 在范围内,因为它是在对象 Ordering 中定义的,它是 java.util.Comparator 的子类,因此您可以使用它来创建另一个订单...

这是针对scala 2.10编译的,好像2.11在这方面有变化,但是当我尝试升级scala时,scalac进入了无限循环。

编辑:只是为了表明我不是一无所知,我暂时用import Ordered._我的替换来修复它import OrderedFix._

/** Avoid implicit cycles between scala Ordered and Ordering */
trait OrderedFix[T] {
    def compare(that :T) :Int

    def < (that :T) = compare(that) <0
    def <=(that :T) = compare(that) <=0
    def > (that :T) = compare(that) >0
    def >=(that :T) = compare(that) >=0

}

object OrderedFix {
    implicit def ordered[T :Ordering](self :T) :OrderedFix[T] = new OrderedFix[T] {
        def compare(that :T) = implicitly[Ordering[T]].compare(self, that)
    }
}

但这很愚蠢,这就是标准库应该提供的......

4

2 回答 2

3

许多人认为使用该Ordered特征是不好的风格。首选方法是坚持Ordering类型类。以下是使用 just 的示例Ordering

val (d1, d2) = (Option(new Date()), Option(new Date()))
val ord = Ordering[Option[Date]]
import ord._

compare(d1, d2)

d1 < d2
d1 equiv d2

在这里,import两者都可以使您compare进入作用域以及允许最后两行中显示的中缀运算符的扩展方法。

于 2014-08-06T19:16:26.243 回答
0

您可以使用以下Comparable方法避免模棱两可的隐式转换compareTo

import Ordered.orderingToOrdered
import java.util.Date

val (d1, d2) = (Option(new Date()), Option(new Date()))
d1 compareTo d2

(我还是推荐Ordering

于 2014-08-07T16:08:33.150 回答