Use the type class pattern.
For one example, consider how Ordering
is implemented. It adds a method -- compare
-- to a set of closed classes, but it does so not by adding the method directly but, instead, providing an instance that has such a method for that particular class. Ordering[Int]
, to continue with the example, is implemented like this:
trait IntOrdering extends Ordering[Int] {
def compare(x: Int, y: Int) =
if (x < y) -1
else if (x == y) 0
else 1
}
implicit object Int extends IntOrdering
That is, the object Ordering.Int
(for this is inside the object Ordering
) implements a method compare
that takes two Int
as a parameter. This object is provided implicitly, so that the user does not need to pass it explicitly. List
's sorted
method takes advantage of this:
def sorted[B >: A](implicit ord: math.Ordering[B]): List[A]
Then it can call ord.compare
on instances of the list to order them. I encourage you to look at Ordering
to understand what it is doing.