Skip to content

Order

Defines comparison functions for ordered values.

An Order<A> compares two A values and returns whether the first is less than, equal to, or greater than the second. Orders are used for sorting, choosing minimum or maximum values, checking ranges, and building ordered data structures. This module includes built-in orders, constructors for custom orders, tools for reversing and combining comparisons, tuple and struct helpers, comparison predicates, clamping, and reducer support.

25 exports Added in v2.0.0 Source

Combinators

flip

Added in v4.0.0 Source

Creates a new Order that reverses the comparison order of the input Order.

When to use

Use when you need the reverse of an existing order.

Details

Returns a new order that swaps the arguments before comparison. If the original order returns -1, the flipped order returns 1, and vice versa. Equal comparisons remain 0.

See

  • combine to combine orders for multi-criteria comparison

Signature

declare function flip<A>(O: Order<A>): Order<A>;

Struct

Added in v4.0.0 Source

Creates an Order for structs by applying the given Orders to each property in sequence.

When to use

Use when you need multi-field ordering for objects with known properties.

Details

Compares structs field-by-field in the key order of the fields object and stops at the first non-zero comparison result. Field order matters: earlier fields take precedence. The result is 0 only if all fields are equal.

See

  • combine to combine orders manually
  • mapInput to extract and compare by a single property

Signature

declare function Struct<
  R extends {
    [x: string]: Order<any>;
  },
>(fields: R): Order<{ [K in string | number | symbol]: [R[K]] extends [Order<A>] ? A : never }>;

Tuple

Added in v4.0.0 Source

Creates an Order for a tuple type based on orders for each element.

When to use

Use when you need fixed-length tuple ordering with per-position orders.

Details

Compares tuples element-by-element using the corresponding order and stops at the first non-zero comparison result. Tuples must have the same length as the order collection, and the result is 0 only if all elements are equal.

See

  • Array to compare arrays with length consideration

Signature

declare function Tuple<Elements extends readonly Array<Order<any>>>(elements: Elements): Order<{ [I in string | number | symbol]: [Elements[I]] extends [Order<A>] ? A : never }>

Combining

combine

Added in v2.0.0 Source

Combines two Order instances to create a new Order that first compares using the first Order, and if the values are equal, then compares using the second Order.

When to use

Use when you need tie-breaking with exactly two orders.

Details

First applies the first order. If the result is non-zero, that result is returned; otherwise, the second order is applied. The result is the first non-zero comparison result, or 0 if both orders return 0.

See

  • combineAll to combine multiple orders from a collection
  • mapInput to transform orders to work with different types

Signature

declare const combine: {
  <A>(that: Order<A>): (self: Order<A>) => Order<A>;
  <A>(self: Order<A>, that: Order<A>): Order<A>;
};

combineAll

Added in v2.0.0 Source

Combines all Order instances in the provided collection into a single Order. The resulting Order compares using each Order in sequence until a non-zero result is found.

When to use

Use when you need tie-breaking across a variable number of orders.

Details

Applies orders in iteration order and short-circuits on the first non-zero result. It returns 0 only if all orders return 0.

See

Signature

declare function combineAll<A>(collection: Iterable<Order<A>>): Order<A>;

Comparisons

clamp

Added in v2.0.0 Source

Restricts a value between a minimum and a maximum according to the given order.

When to use

Use when you need to clamp a value to an inclusive range according to an Order.

Details

Returns the value itself when it is between minimum and maximum, inclusive. Values below the range return minimum, and values above the range return maximum. The minimum must be less than or equal to the maximum according to the order.

See

  • min for the minimum of two values
  • max for the maximum of two values
  • isBetween to check if a value is within a range

Signature

declare function clamp<A>(O: Order<A>): {
  (options: { maximum: A; minimum: A }): (self: A) => A;
  (
    self: A,
    options: {
      maximum: A;
      minimum: A;
    },
  ): A;
};

max

Added in v2.0.0 Source

Returns the maximum of two values according to the given order. If they are equal, returns the first argument.

When to use

Use when you need to select the larger of two values according to an Order.

Details

Returns the value that compares as greater than or equal to the other value. If values are equal, the first argument is returned.

See

  • min for the minimum of two values
  • clamp to clamp a value between min and max

Signature

declare function max<A>(O: Order<A>): {
  (that: A): (self: A) => A;
  (self: A, that: A): A;
};

min

Added in v2.0.0 Source

Returns the minimum of two values according to the given order. If they are equal, returns the first argument.

When to use

Use when you need to select the smaller of two values according to an Order.

Details

Returns the value that compares as less than or equal to the other value. If values are equal, the first argument is returned.

See

  • max for the maximum of two values
  • clamp to clamp a value between min and max

Signature

declare function min<A>(O: Order<A>): {
  (that: A): (self: A) => A;
  (self: A, that: A): A;
};

Constructors

alwaysEqual

Added in v4.0.0 Source

Creates an Order that considers all values as equal.

When to use

Use when you need an order that treats all values as equal.

Details

Always returns 0 regardless of input values, making it useful as a neutral element in order composition.

See

  • combine to combine with other orders

Signature

declare function alwaysEqual<A>(): Order<A>;

make

Added in v2.0.0 Source

Creates a new Order instance from a comparison function.

When to use

Use when you need a sorting rule not covered by the built-in orders or input mapping helpers, and you can provide a total comparison.

Details

Uses reference equality (===) as a shortcut: if self === that, it returns 0 without calling the comparison function. The comparison function should return -1, 0, or 1, and the returned order satisfies total ordering laws when the comparison function does.

See

  • mapInput to transform an order by mapping the input type
  • combine to combine multiple orders

Signature

declare function make<A>(compare: (self: A, that: A) => -1 | 0 | 1): Order<A>;

makeReducer

Added in v4.0.0 Source

Creates a Reducer for combining Order instances, useful for aggregating orders in collections.

When to use

Use when you need a reducer that combines orders.

Details

Returns a reducer that combines orders using combine, uses alwaysEqual as the identity element for empty collections, and uses combineAll for combining collections of orders. The reducer can be used with fold operations on collections.

See

Signature

declare function makeReducer<A>(): Reducer<Order<A>>;

Instances

BigInt

Added in v4.0.0 Source

Order instance for bigints that compares them numerically.

When to use

Use when you need numeric ordering for bigint values.

Details

Uses standard numeric comparison for bigint values and handles arbitrarily large integers.

See

  • Number for regular number comparisons
  • mapInput to compare objects by a bigint property

Signature

declare const BigInt: Order<bigint>;

Boolean

Added in v4.0.0 Source

Order instance for booleans where false is considered less than true.

When to use

Use when you need boolean ordering where false comes before true.

Details

false is less than true, and equal values return 0.

See

  • mapInput to compare objects by a boolean property

Signature

declare const Boolean: Order<boolean>;

Date

Added in v2.0.0 Source

Order instance for Date objects that compares them chronologically by their timestamp.

When to use

Use when you need chronological ordering for JavaScript date values.

Details

Compares dates by their underlying timestamp in milliseconds since the epoch. Earlier dates are less than later dates. Invalid dates are compared through their getTime() result.

See

  • mapInput to compare objects by a date property

Signature

declare const Date: Order<Date>;

Number

Added in v4.0.0 Source

Order instance for numbers that compares them numerically.

When to use

Use when you need numeric ordering for numbers.

Details

0 is considered equal to -0. All NaN values are considered equal to each other, and any NaN is considered less than any non-NaN number. All other values use standard numeric comparison.

See

  • mapInput to compare objects by a number property
  • BigInt for bigint comparisons

Signature

declare const Number: Order<number>;

String

Added in v4.0.0 Source

Order instance for strings that compares them lexicographically using JavaScript's < operator.

When to use

Use when you need lexicographic string ordering.

Details

Uses lexicographic dictionary ordering. The empty string is less than any non-empty string, and comparisons are case-sensitive.

See

  • mapInput to compare objects by a string property
  • Struct to combine with other orders for struct comparison

Signature

declare const String: Order<string>;

Mapping

mapInput

Added in v2.0.0 Source

Transforms an Order on type A into an Order on type B by providing a function that maps values of type B to values of type A.

When to use

Use when you need to adapt an Order to compare a larger value by one derived property.

Details

Applies the mapping function to both values before comparison. The mapping function should be pure and not have side effects so the ordering properties of the original order are preserved.

See

  • combine to combine mapped orders for multi-criteria comparison
  • Struct to create orders for structs with multiple fields

Signature

declare const mapInput: {
  <B, A>(f: (b: B) => A): (self: Order<A>) => Order<B>;
  <A, B>(self: Order<A>, f: (b: B) => A): Order<B>;
};

Models

Order interface

Added in v2.0.0 Source

Represents a total ordering for values of type A.

When to use

Use when you need to define how values of a type are compared.

Details

An order returns -1 when the first value is less than the second, 0 when the values are equal according to this ordering, and 1 when the first value is greater than the second. It must satisfy total ordering laws: totality, antisymmetry, and transitivity.

See

  • make to create an order from a comparison function
  • Ordering for the result type of comparisons

Signature

interface Order<in A> {
  (self: A, that: A): Ordering;
}

Other

Array

Added in v4.0.0 Source

Signature

declare function Array<A>(O: Order<A>): Order<readonly Array<A>>

Predicates

isBetween

Added in v4.0.0 Source

Checks whether a value is between a minimum and a maximum (inclusive) according to the given order.

When to use

Use when you need range checks that respect domain-specific ordering, such as dates, versions, or custom priorities, instead of JavaScript numeric comparison.

Details

Returns true when the value is greater than or equal to minimum and less than or equal to maximum. Values outside the range return false. Both bounds are inclusive.

See

Signature

declare function isBetween<A>(O: Order<A>): {
  (options: { maximum: A; minimum: A }): (self: A) => boolean;
  (
    self: A,
    options: {
      maximum: A;
      minimum: A;
    },
  ): boolean;
};

Checks whether one value is strictly greater than another according to the given order.

When to use

Use when you need a boolean greater-than predicate using an Order.

Details

Returns true if the order returns 1, meaning the first value is greater than the second. Equal or lesser values return false.

See

Signature

declare function isGreaterThan<A>(O: Order<A>): {
  (that: A): (self: A) => boolean;
  (self: A, that: A): boolean;
};

Checks whether one value is greater than or equal to another according to the given order.

When to use

Use when you need a boolean greater-than-or-equal predicate using an Order.

Details

Returns true if the order returns 1 or 0, and returns false only if the order returns -1.

See

Signature

declare function isGreaterThanOrEqualTo<A>(O: Order<A>): {
  (that: A): (self: A) => boolean;
  (self: A, that: A): boolean;
};

isLessThan

Added in v4.0.0 Source

Checks whether one value is strictly less than another according to the given order.

When to use

Use when you need a boolean less-than predicate using an Order.

Details

Returns true if the order returns -1, meaning the first value is less than the second. Equal or greater values return false.

See

Signature

declare function isLessThan<A>(O: Order<A>): {
  (that: A): (self: A) => boolean;
  (self: A, that: A): boolean;
};

Checks whether one value is less than or equal to another according to the given order.

When to use

Use when you need a boolean less-than-or-equal predicate using an Order.

Details

Returns true if the order returns -1 or 0, and returns false only if the order returns 1.

See

Signature

declare function isLessThanOrEqualTo<A>(O: Order<A>): {
  (that: A): (self: A) => boolean;
  (self: A, that: A): boolean;
};

Utility Types

OrderTypeLambda interface

Added in v2.0.0 Source

Type lambda for the Order type class, used internally for higher-kinded type operations.

When to use

Use when you need to abstract over Order in higher-kinded type code.

Details

This is type-level only, has no runtime representation, and is used internally by the Effect type system.

Signature

interface OrderTypeLambda extends TypeLambda {
  readonly type: Order<unknown>;
}