Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Purpose of PartialOrdering in Scala library

I understand what is partial order from mathematical point of view, but cannot see where and how PartialOrdering type class from Scala library can be used. I searched through whole standard library and there's only one usage: it extended by Ordering. Same story for its primary method tryCompare, it seems isn't used anywhere.

So, what benefits I can have if instead of

case class Foo(x: Int, y: String)

val order = Ordering.by { foo => (foo.x, foo.y) }

I implement a more domain-correct instance:

object PartialFoo extends PartialOrdering[Foo] {
  def tryCompare(a: Foo, b: Foo): Option[Foo] = {
    if (a.x != b.x) None  // Doesn't make sense to compare foos with different xs
    else ???
  }
}

UPD: It also seems like Ordering trait defined with return type Some[Int] (not Option[Int]) and I even cannot use override. Is it intentional?

like image 882
chuwy Avatar asked Nov 09 '22 16:11

chuwy


1 Answers

This seems to be a template for type classes which would represent natural partial orderings for a type.

The point of these classes isn't to be used explicitly, but implicitly in libraries which would allow a user to have access to methods which could only be applied to types with such a natural type class available.

As an example, the Numeric type class, which is for instance an implicit parameter of the sum method of collections, is never actually explicitly provided when doing something like val x = List(1, 2, 3).sum. Instead, scala by default imports a Numeric[Int] object in scope, which allows the compiler to "know" how to sum ints.

Similarly, if one were to develop a method which would only "work" for elements with a natural partial ordering, there would be two options :

  1. create a trait of the likes of PartiallyOrdered and require arguments of this type - this is not very flexible, just compare to the sum method, which can be called on ANY collection

  2. add an implicit parameter of type PartialOrdering[T]to the method, and create implementations for the desired types.

Although I can't find any actual implementations of PartialOrdering which do not also implement Ordering, having this class is still a good thing, as it means any users which would like to implement PartialOrdering, but not Ordering, will also be able to pass Orderings to their method using PartialOrdering's ! eg. Int, String, etc.

So say I create a class A and a partial ordering

APartialOrdering extends PartialOrdering[A].

Because my type A admits no natural ordering, only a partial one. Finally, I create a method

def doSomethingForPartiallyOrdered[T](t: T)(implicit po: PartialOrdering[T]) = _

Now, I can pass objects of type A, but also Int's, Strings, etc.

like image 70
Ulysse Mizrahi Avatar answered Nov 15 '22 05:11

Ulysse Mizrahi