//@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, }