ostrichofevil
ostrichofevil

Reputation: 734

Get Ordering from Ordered in Scala

Is there any way, given an object with the trait Ordered, to get an Ordering which uses the same comparison as the original object?

The reason I want to do this is I have implemented a merge sort with the following signature (the Manifests are just so that I can instantiate new List[T]s and Array[T]s:

def mergeSorted[T : Manifest](li: List[T], ord: Ordering[T]) : List[T]

What I want to do is overload this with a method with this signature:

def mergeSorted[T <: Ordered[T] : Manifest](li: List[T]) : List[T]

This way, I wouldn't have to manually, say, put in the Int ordering if I were sorting Ints. It seems to me that the easies way to implement this would just be to get an Ordering[T] from T somehow. The ScalaDoc seems to say that this is possible through implicits:

Ordered and Ordering both provide implicits allowing them to be used interchangeably.

However, I don't know which implicits to import in order to do this.

Upvotes: 1

Views: 524

Answers (2)

Phasmid
Phasmid

Reputation: 953

If you define:

def mergeSorted[T : Ordering : Manifest](li: List[T]) : List[T]

the compiler will desugar that into

def mergeSorted[T : Manifest](li: List[T])(implicit ev: Ordering[T]) : List[T]

and everything will work just as you want.

Upvotes: 1

Leo C
Leo C

Reputation: 22449

Both math.Ordering and math.Ordered can achieve what you need by means of implicit parameter and implicit conversion, respectively. Depending on which one to use, the mergeSort function will have a signature similar to one of the following:

// Using math.Ordering
def mergeSort[T](li: List[T])(implicit order: Ordering[T]): List[T] = {
  ...
}

// Using math.Ordered
def mergeSort[T <% Ordered[T]](li: List[T]): List[T] = {
  ...
}

For details, this generic merge sort blog post might be of interest to you.

Upvotes: 1

Related Questions