Reputation: 734
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 Manifest
s 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 Int
s. 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
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
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