This commit is contained in:
swrup 2025-11-11 02:07:51 +01:00
parent aa2ff7b2f0
commit 2f3113f55d
11742 changed files with 1223940 additions and 0 deletions

View file

@ -0,0 +1,4 @@
(library
(name ordering)
(public_name ordering)
(synopsis "Element ordering."))

View file

@ -0,0 +1,51 @@
type t =
| Lt
| Eq
| Gt
let of_int n = if n < 0 then Lt else if n = 0 then Eq else Gt
let to_int = function
| Lt -> -1
| Eq -> 0
| Gt -> 1
;;
let to_string = function
| Lt -> "<"
| Eq -> "="
| Gt -> ">"
;;
let is_eq = function
| Eq -> true
| Lt | Gt -> false
;;
let min f x y =
match f x y with
| Eq | Lt -> x
| Gt -> y
;;
let max f x y =
match f x y with
| Eq | Gt -> x
| Lt -> y
;;
let opposite = function
| Lt -> Gt
| Eq -> Eq
| Gt -> Lt
;;
let reverse f a b = opposite (f a b)
module O = struct
let ( let= ) t f =
match t with
| (Lt | Gt) as result -> result
| Eq -> f ()
;;
end

View file

@ -0,0 +1,51 @@
(** Element ordering *)
type t =
| Lt (** Lesser than *)
| Eq (** Equal *)
| Gt (** Greater than *)
val of_int : int -> t
val to_int : t -> int
(** returns the string representation. one of: "<", "=", ">" *)
val to_string : t -> string
val is_eq : t -> bool
val min : ('a -> 'a -> t) -> 'a -> 'a -> 'a
val max : ('a -> 'a -> t) -> 'a -> 'a -> 'a
(** [reverse cmp] takes a comparison function [cmp] and returns a new comparison
function whose comparisons are the opposite of that of [cmp]. *)
val reverse : ('a -> 'a -> t) -> 'a -> 'a -> t
module O : sig
(** A convenient operator for efficiently chaining multiple comparisons
together. For example, you can write
{v
let compare { x; y; z } t =
let open Ordering.O in
let= () = compare_x x t.x in
let= () = compare_y y t.y in
compare_z z t.z
v}
or, a bit less compactly but more symmetrically
{v
let compare { x; y; z } t =
let open Ordering.O in
let= () = compare_x x t.x in
let= () = compare_y y t.y in
let= () = compare_z z t.z in
Eq
v}
to chain three comparisons instead of the usual triply nested [match].
Note that the resulting code can be up to 2x slower than nested [match]ing
due to extra allocations that we are unable to eliminate (as of Nov 2021),
so you should use [let=] only where appropriate. *)
val ( let= ) : t -> (unit -> t) -> t
end