I've got a trait implementing an Ordered trait of Scala:
package stackQuestions
trait ValueTrait[TYPE] extends Ordered[ValueTrait[TYPE]]{
def value: Double
}
and a subclass:
package stackQuestions
class Value[A](list: List[A], function: (A, A) => Double) extends ValueTrait[A] {
private val _value: Double = list.zip(list.tail).map(pair => function(pair._1, pair._2)).sum
override def value: Double = _value
override def compare(that: ValueTrait[A]): Int = {
(this.value - that.value).signum
}
}
Basically, when an object of Value is created with provided function, the value is calculated. What I want to achieve is to sort a collection of Value objects based on their value. This should be guaranteed by Ordered trait. I've written some simple tests for this:
package stackQuestions
import org.scalatest.FunSpec
class ValueTest extends FunSpec {
def evaluationFunction(arg1: Int, arg2: Int): Double = {
if (arg1 == 1 && arg2 == 2) return 1.0
if (arg1 == 2 && arg2 == 1) return 10.0
0.0
}
val lesserValue = new Value(List(1, 2), evaluationFunction) // value will be: 1.0
val biggerValue = new Value(List(2, 1), evaluationFunction) // value will be: 10.0
describe("When to Value objects are compared") {
it("should compare by calculated value") {
assert(lesserValue < biggerValue)
}
}
describe("When to Value objects are stored in collection") {
it("should be able to get max value, min value, and get sorted") {
val collection = List(biggerValue, lesserValue)
assertResult(expected = lesserValue)(actual = collection.min)
assertResult(expected = biggerValue)(actual = collection.max)
assertResult(expected = List(lesserValue, biggerValue))(actual = collection.sorted)
}
}
}
However, when sbt test -Xlog-implicits
I've get error messages:
[info] Compiling 1 Scala source to /project/target/scala-2.11/test-classes ...
[error] /project/src/test/scala/stackQuestions/ValueTest.scala:24:64: diverging implicit expansion for type Ordering[stackQuestions.Value[Int]]
[error] starting with method $conforms in object Predef
[error] assertResult(expected = lesserValue)(actual = collection.min)
[error] ^
[error] /project/src/test/scala/stackQuestions/ValueTest.scala:25:64: diverging implicit expansion for type Ordering[stackQuestions.Value[Int]]
[error] starting with method $conforms in object Predef
[error] assertResult(expected = biggerValue)(actual = collection.max)
[error] ^
[error] /project/src/test/scala/stackQuestions/ValueTest.scala:27:83: diverging implicit expansion for type scala.math.Ordering[stackQuestions.Value[Int]]
[error] starting with method $conforms in object Predef
[error] assertResult(expected = List(lesserValue, biggerValue))(actual = collection.sorted)
[error] ^
[error] three errors found
[error] (Test / compileIncremental) Compilation failed
[error] Total time: 1 s, completed 2018-09-01 08:36:18
I've dug for similar problems and after reading:
- What's a “diverging implicit expansion” scalac message mean?,
- Why am I getting a “ diverging implicit expansion” error when trying to sort instances of an ordered class?,
- How can I solve the Diverging implicit expansion for type,
- scala - Confusing “diverging implicit expansion” error when using “sortBy”,
I get to know that the compiler is confused about how to choose the proper function for comparison. I know that I can circumvent this using sortBy(obj => obj.fitness)
but is there any way to use less verbose sorted
method?