PartialOrderOrEq
If you are using the Cats library, you can define a PartialOrder type class for any data type.
- Scala 3
- Scala 2.13
// Simplified definition.
// See https://typelevel.org/cats/api/cats/kernel/PartialOrder.html for further details
trait PartialOrder[A]:
def partialCompare(x: A, y: A): Double
// Simplified definition.
// See https://typelevel.org/cats/api/cats/kernel/PartialOrder.html for further details
trait PartialOrder[A] {
def partialCompare(x: A, y: A): Double
}
The PartialOrder type provides a method for comparing two objects of the given type, returning a double value of:
- 0.0 if the two objects are equivalent
- -1.0 if
x < y - 1.0 if
x < y NaNifxandycannot be compared.
Cats is also kind enough to provide implicit <, <=, ===, >= and > operators if the given type does not provide them already.
That's all nice, but not every type comes with a given PartialOrder for us to use.
But logically, it must be possible to define a PartialOrder for every type; even if it is very partial!
The couldbe-cats package provides a ready implementation of PartialOrderOrEq:
- Scala 3
- Scala 2.13
trait PartialOrderOrEq[A: CouldHave[PartialOrder]: EqOrEquals]:
def p(x: A, y: A): Double =
CouldHave[PartialOrder, A]
.act(_.partialCompare(x, y))
(if EqOrEquals.e(x, y) then 0.0 else Double.NaN)
trait PartialOrderOrEq[A: EqOrEquals](A: CouldHave[PartialOrder, A]) {
def p(x: A, y: A): Double =
CouldHave[PartialOrder, A]
.act(_.partialCompare(x, y))
(if (EqOrEquals.e(x, y)) 0.0 else Double.NaN)
}
This is a "best attempt" at a partial order for any given type.
In the following function
- Scala 3
- Scala 2.13
def yourFunction[A: PartialOrderOrEq](x: A, y: A):
// ...
PartialOrderOrEq.p(x, y)
// ...
def yourFunction[A: PartialOrderOrEq](x: A, y: A) {
// ...
PartialOrderOrEq.p(x, y)
// ...
}
the following rules will be applied:
- if a given
PartialOrder(or a completeOrder, which extends the trait) exists, then that instance will be used to perform the comparison - otherwise, if a given
Eq(Cats Equality) instance exists, then the function will return 0.0 ifx === y;NaNotherwise - finally, if we still have no comparison, the two values will be compared using the JVM
.equals()method; returning 0.0 ifx.equals(y)orNaNotherwise.