0

I want to define a collection class and require its element being Ordered

Considering the code below:

class MyCollection[K: Ordered[K]] {
  def func(seq: Seq[K]): Unit = {
    seq.sorted
  }
}

The compiler will report error No implicit Ordering defined for ord: Ordering[K]

Am I doing anything wrong? Given that we already have the constraint K: Ordered[K]

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
Ziqi Liu
  • 2,931
  • 5
  • 31
  • 64

1 Answers1

3

You should use:

  • either Ordered with

    • F-bound

      class MyCollection[K <: Ordered[K]] {
        def func(seq: Seq[K]): Unit =
          seq.sorted
      }
      
    • generalized constraint

      class MyCollection[K](implicit ev: K <:< Ordered[K]) {
        def func(seq: Seq[K]): Unit =
          seq.sorted
      }
      
    • view bound

      class MyCollection[K](implicit ev: K => Ordered[K]) {
        def func(seq: Seq[K]): Unit =
          seq.sorted
      }
      

      (from stronger to weaker assumption)

  • or Ordering with context bound

    class MyCollection[K: Ordering] {
      def func(seq: Seq[K]): Unit =
        seq.sorted
    }
    

Ordered and Ordering are now defined so that the constraints K => Ordered[K] and K: Ordering are actually equivalent. Indeed, Ordering.ordered transforms one into another in one direction, Ordered.orderingToOrdered transforms in the other

def test[K](implicit ev: K => Ordered[K]) =
  implicitly[Ordering[K]] // compiles

def test[K: Ordering] =
  implicitly[K => Ordered[K]] // compiles

The context bound MyCollection[K: Ordering] is a syntax sugar for MyCollection[K](implicit ev: Ordering[K]). That's why [K: Ordered[K]] can't compile at all because of kind mismatch.

Ordering is a type class but Ordered is not. Ordered is an ordinary OOP trait (you're extending it in OOP style rather than define its implicit instances in FP style). That's why although [K: Ordered] compiles but it would be incorrect semantically (implicits will not be found).

Ordering and Ordered and comparing Options

Scala Ordering, Ordered, and View Bound

Get Ordering from Ordered in Scala

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66