//@NO-IMPLICIT-PRELUDE
//! Functionality for ordering and comparison.
let { Bool, Ordering } = import! std.types
let { Semigroup } = import! std.semigroup
let { Monoid } = import! std.monoid
/// `Eq a` defines equality (==) on `a`
#[implicit]
type Eq a = {
/// Tests whether the values are equal.
(==) : a -> a -> Bool,
}
#[infix(left, 4)]
let (==) ?eq : [Eq a] -> a -> a -> Bool = eq.(==)
/// Tests whether the values are not equal.
#[infix(left, 4)]
let (/=) ?eq l r : [Eq a] -> a -> a -> Bool = if (eq.(==) l r) then False else True
/// `Ord a` defines an ordering on `a`
#[implicit]
type Ord a = {
eq : Eq a,
/// Compares two values and returns wheter the first is less than, equal or greater than the second.
compare : a -> a -> Ordering,
}
let compare ?ord : [Ord a] -> a -> a -> Ordering = ord.compare
/// Returns whether `l` is less than or equal to `r`.
#[infix(left, 4)]
let (<=) l r : [Ord a] -> a -> a -> Bool =
match compare l r with
| LT -> True
| EQ -> True
| GT -> False
/// Returns whether `l` is less than `r`.
#[infix(left, 4)]
let (<) l r : [Ord a] -> a -> a -> Bool =
match compare l r with
| LT -> True
| EQ -> False
| GT -> False
/// Returns whether `l` is greater than `r`.
#[infix(left, 4)]
let (>) l r : [Ord a] -> a -> a -> Bool =
match compare l r with
| LT -> False
| EQ -> False
| GT -> True
/// Returns whether `l` is greater than or equal to `r`.
#[infix(left, 4)]
let (>=) l r : [Ord a] -> a -> a -> Bool =
match compare l r with
| LT -> False
| EQ -> True
| GT -> True
let min l r : [Ord a] -> a -> a -> a =
if l <= r then l else r
let max l r : [Ord a] -> a -> a -> a =
if r >= l then r else l
let semigroup : Semigroup Ordering = {
append = \x y ->
match x with
| EQ -> y
| _ -> x,
}
let monoid : Monoid Ordering = {
semigroup,
empty = EQ,
}
{
Eq,
(==), (/=),
Bool,
Ord,
compare, (<), (<=), (>=), (>), min, max,
Ordering,
semigroup,
monoid,
}