49

While trying to find a solution to another question ([1]) I came across a diverging implicit expansion error. I'm looking for an explanation about what this means

Here's the use case:

scala> implicit def ordering[T](implicit conv: T => Ordered[T], res: Ordering[Ordered[T]]) = Ordering.by(conv)
ordering: [T](implicit conv: (T) => Ordered[T],implicit res: Ordering[Ordered[T]])scala.math.Ordering[T]

scala> def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted
<console>:6: error: diverging implicit expansion for type Ordering[T]
starting with method ordering in object $iw
       def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted
                                                ^
1
  • I solved this error in a very different context, which might help someone else. The following did not work in my case: val seq: Seq[Int] = in.readData() but by helping the type inferencer by explicitly stating the type parameters of the method, then it worked: val seq = in.readData[Seq[Int]](). However, stating type parameters of sorted does not seem to help here for the OT. Oct 2, 2018 at 7:52

1 Answer 1

24

If you run this in scala with the -Xlog-implicits argument passed, you get more information:

scala.this.Prefed.conforms is not a valid implicit value for (T) => Ordered[T] because:

type mismatch:

found : <:<[T,T]

required: (T) => Ordered[T]

scala.this.predef.conforms is not a valid implicit value for (Ordered[T]) => Ordered[Ordered[T]] because:

type mismatch:

found : <:<[Ordered[T], Ordered[T]]

required : (Ordered[T]) => Ordered[Ordered[T]]

math.this.Ordering.ordered is not a valid implicit value for Ordering[T] because:

type arguments [T] do not conform to method ordered's type parameter bounds [A <: scala.math.Ordered[A]]

This is mostly speculation, but would seem to make some sense. I will try to investigate further:

This seems to suggest that there are three implicits that are being considered here. Ultimately, the signature of sorted requires it to find something of type Ordering[T]. So it's trying to construct your implicit function ordering. Firstly, it's trying to fill in conv by finding an implicit of type (T) => Ordered[T], where it's searching in Predef - which seems like barking up the wrong tree. It's then trying to find an implicit for (Ordered[T]) => Ordered[Ordered[T]] in the same place, since by takes an implicit parameter of type Ordering[S], where S is Ordered[T] by virtue of conv. So it can't construct ordering.

It then tries to use ordering in math.Ordering, but this also doesn't fit. However, I think this is what's giving the somewhat confusing 'diverging implicits' message. The problem isn't that they're diverging, it's that there isn't a suitable one in scope, but it's being confused by the fact that there are two paths to go down. If one tries to define def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted without the implicit ordered function, then it fails with just a nice message saying that it can't find a suitable implicit.

1
  • 1
    I don't know, I thought it means that there's recursion. "Two paths to go down" would be "ambiguous implicits" IIUC.
    – nafg
    Jul 13, 2012 at 20:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.