Order
Формальное определение
Order
предназначен для типов, которые имеют порядок. Он расширяет тип Equal
.
Order
охватывает все стандартные функции сравнения, такие как >
, <
, >=
и <=
,
а также с его помощью можно реализовать операции нахождения максимума, минимума, сортировку двух элементов и реверсивный Order
.
Order
должен удовлетворять следующим законам (помимо законов Equal
):
-
Антисимметричность:
- если
f1 < f2
, тоf2 > f1
, - если
f1 <= f2
, тоf2 >= f1
, - и т.п.
- если
-
Транзитивность:
- если
f1 < f2
иf2 <= f3
, тоf1 < f3
, - если
f1 == f2
иf2 <= f3
, тоf1 <= f3
, - если
f1 == f2
иf2 == f3
, тоf1 == f3
, - и т.п.
- если
-
Полнота:
- либо
a <= b
, либоb <= a
- либо
-
Соответствие
Order
иEqual
:equal(f1, f2)
равноtrue
тогда и только тогда, когдаorder(f1, f2)
равноOrdering.EQ
Определение в виде кода на Scala
trait Equal[F]:
def equal(a1: F, a2: F): Boolean
enum Ordering:
case LT
case EQ
case GT
trait Order[F] extends Equal[F]:
self =>
def order(x: F, y: F): Ordering
def equal(x: F, y: F): Boolean = order(x, y) == Ordering.EQ
def lessThan(x: F, y: F): Boolean = order(x, y) == Ordering.LT
def lessThanOrEqual(x: F, y: F): Boolean = order(x, y) != Ordering.GT
def greaterThan(x: F, y: F): Boolean = order(x, y) == Ordering.GT
def greaterThanOrEqual(x: F, y: F): Boolean = order(x, y) != Ordering.LT
def max(x: F, y: F): F = if greaterThanOrEqual(x, y) then x else y
def min(x: F, y: F): F = if lessThan(x, y) then x else y
def sort(x: F, y: F): (F, F) = if lessThanOrEqual(x, y) then (x, y) else (y, x)
def reverseOrder: Order[F] = new Order[F]:
def order(x: F, y: F): Ordering = self.order(y, x)
override def equal(x: F, y: F) = self.equal(x, y)
override def reverseOrder = self
Реализация
Реализация в Cats
import cats.*
import cats.implicits.*
1.0 compare 2.0
// val res0: Int = -1
1.0 max 2.0
// val res1: Double = 2.0
Реализация в ScalaZ
import scalaz.*
import Scalaz.*
1.0 ?|? 2.0 // Ordering.LT
1.0 lt 2.0 // true
2.0 gt 1.0 // true
1.0 lte 2.0 // true
2.0 gte 1.0 // true
1 max 2 // 2
1 min 2 // 1
Метод ?|?
в ScalaZ возвращает результат сравнения Ordering: LT, GT или EQ
.
Реализация в Spire
import spire.algebra.Order
import spire.math.Rational
Order.comparison(Rational(1, 2), Rational(1, 3)) // GreaterThan
Order.gt(Rational(1, 2), Rational(1, 3)) // true
Order.gteqv(Rational(1, 2), Rational(1, 3)) // true
Order.lt(Rational(1, 2), Rational(1, 3)) // false
Order.lteqv(Rational(1, 2), Rational(1, 3)) // false
Order.min(Rational(1, 2), Rational(1, 3)) // 1/3
Order.max(Rational(1, 2), Rational(1, 3)) // 1/2
Ссылки: