# Module `Order_magic`

Polymorphic "magic" functions for structural comparison.

```
open Order.Magic
let () =
assert ('A' < 'Z');
assert (max "abc" "xyz" = "xyz")
```

**Warning:** The polymorphic functions in `Magic`

are provided for convenience and must be used with care: they are less efficient than the specialized versions and may cause runtime errors if functions, or other non-comparable values, are compared. Instead of using `Magic`

.min prefer the monomorphic `min`

if you are working with integer values. Custom data types can implement their own specialized equality and ordering interfaces.

## Polymorphic Equality

`val (=) : 'a -> 'a -> bool`

`a = b`

tests for structural equality of`a`

and`b`

. Mutable structures (*e.g.*references and arrays) are equal if and only if their current contents are structurally equal, even if the two mutable objects are not the same physical object (as tested with`is`

).

`val (<>) : 'a -> 'a -> bool`

`a <> b`

is`not (a = b)`

,*i.e.*, the negation of`(=)`

.

## Polymorphic Ordering

`val compare : 'a Order.comparator`

`compare a b`

returns`0`

if`a`

is equal to`b`

,`-1`

if`a`

is less than`b`

, and`1`

if`a`

is greater than`b`

. The ordering implemented by`compare`

is compatible with the comparison predicates`==`

,`<`

and`>`

defined above, with one difference on the treatment of the float value`nan`

. Namely, the comparison predicates treat`nan`

as different from any other float value, including itself; while`compare`

treats`nan`

as equal to itself and less than any other float value. This treatment of`nan`

ensures that`compare`

defines a total ordering relation.- raises Invalid_argument
if function values are compared for equality.

**Warning:**Equality between cyclic data structures may not terminate.

`val comparing : ('a -> 'b) -> 'a Order.comparator`

Applies a projection function to obtain a comparable value of type

`'b`

.`comparing f`

is defined as`Comparator.by f Magic.compare`

.`type person = { name : string; age : int } let by_age_descending : person comparator = Comparator.descending (comparing (fun p -> p.age)) let () = [{ name = "Alice"; age = 24 }; { name = "Bob"; age = 19 }; { name = "Craig"; age = 45 }] |> List.sort (Comparator.to_integral by_age_descending) |> List.iter (fun p -> print_endline p.name)`

`val (<) : 'a -> 'a -> bool`

`val (>) : 'a -> 'a -> bool`

`val (<=) : 'a -> 'a -> bool`

`val (>=) : 'a -> 'a -> bool`

**Structural ordering functions.**These functions coincide with the usual orderings over integers, characters, strings, byte sequences and floating-point numbers, and extend them to a total ordering over all types. The ordering is compatible with

`(=)`

. As in the case of`(=)`

, mutable structures are compared by contents.- raises Invalid_argument
if function values are compared for equality.

**Warning:**Equality between cyclic data structures may not terminate.

`val min : 'a -> 'a -> 'a`

`min a b`

returns the smaller of the two arguments. The result is unspecified if one of the arguments contains the float value`nan`

.- raises Invalid_argument
if function values are compared for equality.

**Warning:**Equality between cyclic data structures may not terminate.`assert (min 2 5 = 2); assert (min [1; 2; 3] [2; 3; 4] = [1; 2; 3])`

`val max : 'a -> 'a -> 'a`

`max a b`

returns the greater of the two arguments. The result is unspecified if one of the arguments contains the float value`nan`

.- raises Invalid_argument
if function values are compared for equality.

**Warning:**Equality between cyclic data structures may not terminate.`assert (max 2 5 = 5); assert (max [1; 2; 3] [2; 3; 4] = [2; 3; 4])`