Implicit conversion causes stack overflow

The following code fragment worked perfectly, after some changes to the code in different files, I began to receive as a result of a recursive invocation of an implicit conversion. This has ever happened to anyone, and if so, what a fix.

implicit def comparable2ordered[A <: Comparable[_]](x: A): Ordered[A] =
new Ordered[A] with Proxy {
  val self = x

  def compare(y: A): Int = {
    self.compareTo(y)
  }
} 
+3
source share
1 answer

Firstly, I think the reason is use [A <: Comparable[_]]. The existential type in practice means that you cannot actually compare Awith everything. This means that the compiler "selects" the implicit conversion to re-call in the call self.compareTo(hence recursion). You will see this if you would use the -XprintTypes compiler switch

So what to do?


Ordering a Ordered. .

implicit def comp2ord[A <: Comparable[A]] = new Ordering[A] {
  def compare(x : A, y : A) = x compareTo y
}

Ordered:

implicit def ordering2order[A : Ordering](x : A) = new Ordered[A] {
  def compare(y : A) = implicitly[Ordering[A]].compare(x, y)
}

:

scala> val df = new java.text.SimpleDateFormat("yyyy-MM-dd")
df: java.text.SimpleDateFormat = java.text.SimpleDateFormat@f67a0200

scala> TreeSet(df.parse("2011-03-04"), df.parse("2010-05-06"))
<console>:13: error: could not find implicit value for parameter ord: Ordering[java.util.Date]
   TreeSet(df.parse("2011-03-04"), df.parse("2010-05-06"))
          ^

...

scala> implicit def comp2ord[A <: Comparable[A]] = new Ordering[A] {
 | def compare(x : A, y : A) = x compareTo y
 | }
comp2ord: [A <: java.lang.Comparable[A]]java.lang.Object with Ordering[A]

scala> TreeSet(df.parse("2011-03-04"), df.parse("2010-05-06"))
res1: scala.collection.immutable.TreeSet[java.util.Date] = TreeSet(Fri Mar 04 00:00:00 GMT 2011, Thu May 06 00:00:00 BST 2010)

, Ordering Ordered, scala <, >= ..

scala> implicit def ordering2order[A : Ordering](x : A) = new Ordered[A] {
 | def compare(y : A) = implicitly[Ordering[A]].compare(x, y)
 | }
ordering2order: [A](a: A)(implicit evidence$1: Ordering[A])java.lang.Object with Ordered[A]

scala> df.parse("2010-04-05") < df.parse("2009-01-01")
res2: Boolean = false

, A Java, raw-type Comparable, :

implicit def comp2ord(x : DateTime) = new Ordered[DateTime] {
  def compare(y : DateTime) = x compareTo y
}
+4

Source: https://habr.com/ru/post/1785733/


All Articles