Why am I getting a “ diverging implicit expansion”

2019-09-03 07:41发布

问题:

There are a lot of questions on the subject but after one hour of reading, I still cannot understand what I am doing wrong. Here is a minimal example of the code I have (Scala 2.11):

object Anomalies {

    sealed abstract class AnomalyType(val priority: Int) 
                    extends Ordered[AnomalyType] {
        override def compare(that: AnomalyType): Int =
            this.priority - that.priority
        def name = toString()
    }

    case object CRITICAL extends AnomalyType(0)
    case object SERIOUS extends AnomalyType(1)
    case object WARN extends AnomalyType(2)
}

When I try a basic comparison, it works fine:

scala> Anomalies.CRITICAL < Anomalies.WARN
res17: Boolean = true

Yet, when trying to order a list, the compiler yells at me:

scala> Seq(Anomalies.CRITICAL, Anomalies.WARN).max
<console>:26: error: diverging implicit expansion for type
    Ordering[Anomalies.AnomalyType with Product with Serializable]
    starting with method $conforms in object Predef
        Seq(Anomalies.CRITICAL, Anomalies.WARN).max

EDIT: Thanks to Dmytro Mitin I now know that Seq[Anomalies.AnomalyType](Anomalies.CRITICAL, Anomalies.WARN).max and Seq(Anomalies.CRITICAL, Anomalies.WARN).max[Anomalies.AnomalyType] are working.

Can anyone help me understand the error and why the specifying the type fixes it? Is there a way not to have to specify it explicitly?

回答1:

It's enough to specify type parameter:

Seq[Anomalies.AnomalyType](Anomalies.CRITICAL, Anomalies.WARN).max // WARN

or

Seq(Anomalies.CRITICAL, Anomalies.WARN).max[Anomalies.AnomalyType] // WARN


回答2:

The type inferred for your sequence is Seq[Anomalies.AnomalyType with Product with Serializable]. Check out this blog post about Product with Serializable for what's happening and how to fix it.