2

I want to make my case class Event[K, V] be ordered by key K always. But I need to be able to compare Events of different values V. How can I solve this diverging implicit expansion?

import scala.math.Ordering

object Event {
  case class Event[K, V](key: K, value: V)
    (implicit o: Ordering[K]) extends Ordered[Event[K, _]] {
      override def compare(that: Event[K, _]): Int = o.compare(key, that.key)
    }
}

object Main extends App {
  // mimicking a librarys function 
  def lala[O](e: O)(implicit ordering: Ordering[O]) = ???

  val b = Event.Event("a", 12) <= Event.Event("a", 11.99)    
  lala(Event.Event("a", 12))
}

The call to lala does not compile because of this diverging implicit expansion:

diverging implicit expansion for type   
scala.math.Ordering[Event.Event[String,Int]] starting with method $conforms 
in object Predef lala(Event.Event("a", 12))
AbyxDev
  • 1,363
  • 16
  • 30
KIC
  • 5,887
  • 7
  • 58
  • 98

1 Answers1

0

If your library method expects an Ordering instance for your type, you should provide that indead of extended Ordered, which is totally underalted from a compiler point of view. Try the following instead:

case class Event[K, V](key: K, value: V)

object Event {
  implicit def eventOrdering[K, V](implicit o: Ordering[K]) =
    new Ordering[Event[K, V]] {
      // ...
    }
}
OlivierBlanvillain
  • 7,701
  • 4
  • 32
  • 51
  • Hmm ... But I want to to compare Event with differnt values V. And as soon as I remove the V in `implicit def eventOrdering[K, _]` I will end up with the same compiler error. – KIC Mar 29 '17 at 19:34
  • If you library requires an `implicit Ordering[O]`, and `O =:= Event[K, V]`, this is the implicit you need to implement, there is no way around that. – OlivierBlanvillain Mar 29 '17 at 19:38
  • Ok, I got it now .. it seems to work by using both your `implicit eventOrdering` and still keep the case class as `case class Event[K, V](key: K, value: V) (implicit o: Ordering[K]) extends Ordered[Event[K, _]] {...` – KIC Mar 29 '17 at 19:43