Order.ts
Order.ts overview
Section titled “Order.ts overview”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.
Since v2.0.0
Exports Grouped by Category
Section titled “Exports Grouped by Category”- combinators
- combining
- comparisons
- constructors
- instances
- mapping
- predicates
- type class
- type lambdas
- utils
combinators
Section titled “combinators”Creates an Order for arrays by applying the given Order to each element, then comparing by length if all elements are equal.
When to use
Use when you need lexicographic ordering for arrays of one element type.
Details
Compares arrays element-by-element using the provided order and stops at the
first non-zero comparison result. If all elements are equal, shorter arrays
are less than longer arrays. The result is 0 only if arrays have the same
length and all elements are equal.
Example (Ordering array elements)
import { Order } from "effect"
const arrayOrder = Order.Array(Order.Number)
console.log(arrayOrder([1, 2], [1, 3])) // -1console.log(arrayOrder([1, 2], [1, 2, 3])) // -1 (shorter array is less)console.log(arrayOrder([1, 2, 3], [1, 2])) // 1 (longer array is greater)console.log(arrayOrder([1, 2], [1, 2])) // 0See
Tuplefor type-safe tuple ordering
Signature
declare const Array: <A>(O: Order<A>) => Order<ReadonlyArray<A>>Since v4.0.0
Struct
Section titled “Struct”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.
Example (Ordering structs)
import { Order } from "effect"
const personOrder = Order.Struct({ name: Order.String, age: Order.Number})
const person1 = { name: "Alice", age: 30 }const person2 = { name: "Bob", age: 25 }const person3 = { name: "Alice", age: 25 }
console.log(personOrder(person1, person2)) // -1 (Alice < Bob)console.log(personOrder(person1, person3)) // 1 (same name, 30 > 25)console.log(personOrder(person1, person1)) // 0See
combineto combine orders manuallymapInputto extract and compare by a single property
Signature
declare const Struct: <const R extends { readonly [x: string]: Order<any> }>( fields: R) => Order<{ [K in keyof R]: [R[K]] extends [Order<infer A>] ? A : never }>Since v4.0.0
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.
Example (Ordering tuples)
import { Order } from "effect"
const tupleOrder = Order.Tuple([Order.Number, Order.String])
console.log(tupleOrder([1, "a"], [2, "b"])) // -1console.log(tupleOrder([1, "b"], [1, "a"])) // 1console.log(tupleOrder([1, "a"], [1, "a"])) // 0See
Arrayto compare arrays with length consideration
Signature
declare const Tuple: <const Elements extends ReadonlyArray<Order<any>>>( elements: Elements) => Order<{ readonly [I in keyof Elements]: [Elements[I]] extends [Order<infer A>] ? A : never }>Since v4.0.0
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.
Example (Reversing an Order)
import { Order } from "effect"
const flip = Order.flip(Order.Number)
console.log(flip(1, 2)) // 1console.log(flip(2, 1)) // -1console.log(flip(1, 1)) // 0See
combineto combine orders for multi-criteria comparison
Signature
declare const flip: <A>(O: Order<A>) => Order<A>Since v4.0.0
combining
Section titled “combining”combine
Section titled “combine”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.
Example (Combining two Orders)
import { Order } from "effect"
const byAge = Order.mapInput(Order.Number, (person: { name: string; age: number }) => person.age)const byName = Order.mapInput(Order.String, (person: { name: string; age: number }) => person.name)const byAgeAndName = Order.combine(byAge, byName)
const person1 = { name: "Alice", age: 30 }const person2 = { name: "Bob", age: 30 }const person3 = { name: "Charlie", age: 25 }
console.log(byAgeAndName(person1, person2)) // -1 (Same age, Alice < Bob)console.log(byAgeAndName(person1, person3)) // 1 (Alice (30) > Charlie (25))See
combineAllto combine multiple orders from a collectionmapInputto 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>}Since v2.0.0
combineAll
Section titled “combineAll”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.
Example (Combining multiple Orders)
import { Order } from "effect"
const byAge = Order.mapInput(Order.Number, (person: { name: string; age: number }) => person.age)const byName = Order.mapInput(Order.String, (person: { name: string; age: number }) => person.name)
const combinedOrder = Order.combineAll([byAge, byName])
const person1 = { name: "Alice", age: 30 }const person2 = { name: "Bob", age: 30 }
console.log(combinedOrder(person1, person2)) // -1 (Same age, Alice < Bob)See
combineto combine two ordersmakeReducerto create a reducer for combining orders
Signature
declare const combineAll: <A>(collection: Iterable<Order<A>>) => Order<A>Since v2.0.0
comparisons
Section titled “comparisons”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.
Example (Clamping values)
import { Order } from "effect"
const clamp = Order.clamp(Order.Number)({ minimum: 1, maximum: 5 })
console.log(clamp(3)) // 3console.log(clamp(0)) // 1console.log(clamp(6)) // 5See
minfor the minimum of two valuesmaxfor the maximum of two valuesisBetweento check if a value is within a range
Signature
declare const clamp: <A>(O: Order<A>) => { (options: { minimum: A; maximum: A }): (self: A) => A (self: A, options: { minimum: A; maximum: A }): A}Since v2.0.0
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.
Example (Selecting the maximum value)
import { Order } from "effect"
const maxNumber = Order.max(Order.Number)
console.log(maxNumber(1, 2)) // 2console.log(maxNumber(2, 1)) // 2console.log(maxNumber(1, 1)) // 1See
minfor the minimum of two valuesclampto clamp a value between min and max
Signature
declare const max: <A>(O: Order<A>) => { (that: A): (self: A) => A; (self: A, that: A): A }Since v2.0.0
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.
Example (Selecting the minimum value)
import { Order } from "effect"
const minNumber = Order.min(Order.Number)
console.log(minNumber(1, 2)) // 1console.log(minNumber(2, 1)) // 1console.log(minNumber(1, 1)) // 1See
maxfor the maximum of two valuesclampto clamp a value between min and max
Signature
declare const min: <A>(O: Order<A>) => { (that: A): (self: A) => A; (self: A, that: A): A }Since v2.0.0
constructors
Section titled “constructors”alwaysEqual
Section titled “alwaysEqual”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.
Example (Ordering with an always-equal Order)
import { Order } from "effect"
const alwaysEqualOrder = Order.alwaysEqual<number>()
console.log(alwaysEqualOrder(1, 2)) // 0console.log(alwaysEqualOrder(2, 1)) // 0console.log(alwaysEqualOrder(1, 1)) // 0See
combineto combine with other orders
Signature
declare const alwaysEqual: <A>() => Order<A>Since v4.0.0
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.
Example (Creating an Order)
import { Order } from "effect"
const byAge = Order.make<{ name: string; age: number }>((self, that) => { if (self.age < that.age) return -1 if (self.age > that.age) return 1 return 0})
console.log(byAge({ name: "Alice", age: 30 }, { name: "Bob", age: 25 })) // 1console.log(byAge({ name: "Alice", age: 25 }, { name: "Bob", age: 30 })) // -1See
mapInputto transform an order by mapping the input typecombineto combine multiple orders
Signature
declare const make: <A>(compare: (self: A, that: A) => -1 | 0 | 1) => Order<A>Since v2.0.0
makeReducer
Section titled “makeReducer”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.
Example (Creating a Reducer)
import { Order } from "effect"
const reducer = Order.makeReducer<number>()const orders = [Order.Number, Order.flip(Order.Number)]
const combined = reducer.combineAll(orders)console.log(combined(1, 2)) // -1 (uses first order)See
combineto combine two orderscombineAllto combine multiple ordersReducerfor reducing orders as a collection operation
Signature
declare const makeReducer: <A>() => Reducer.Reducer<Order<A>>Since v4.0.0
instances
Section titled “instances”BigInt
Section titled “BigInt”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.
Example (Ordering BigInts)
import { Order } from "effect"
console.log(Order.BigInt(1n, 2n)) // -1console.log(Order.BigInt(2n, 1n)) // 1console.log(Order.BigInt(1n, 1n)) // 0See
Numberfor regular number comparisonsmapInputto compare objects by a bigint property
Signature
declare const BigInt: Order<bigint>Since v4.0.0
Boolean
Section titled “Boolean”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.
Example (Ordering booleans)
import { Order } from "effect"
console.log(Order.Boolean(false, true)) // -1console.log(Order.Boolean(true, false)) // 1console.log(Order.Boolean(true, true)) // 0See
mapInputto compare objects by a boolean property
Signature
declare const Boolean: Order<boolean>Since v4.0.0
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.
Example (Ordering Dates)
import { Order } from "effect"
const date1 = new Date("2023-01-01")const date2 = new Date("2023-01-02")
console.log(Order.Date(date1, date2)) // -1console.log(Order.Date(date2, date1)) // 1console.log(Order.Date(date1, date1)) // 0See
mapInputto compare objects by a date property
Signature
declare const Date: Order<Date>Since v2.0.0
Number
Section titled “Number”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.
Example (Ordering numbers)
import { Order } from "effect"
console.log(Order.Number(1, 1)) // 0console.log(Order.Number(1, 2)) // -1console.log(Order.Number(2, 1)) // 1
console.log(Order.Number(0, -0)) // 0console.log(Order.Number(NaN, 1)) // -1See
mapInputto compare objects by a number propertyBigIntfor bigint comparisons
Signature
declare const Number: Order<number>Since v4.0.0
String
Section titled “String”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.
Example (Ordering strings)
import { Order } from "effect"
console.log(Order.String("apple", "banana")) // -1console.log(Order.String("banana", "apple")) // 1console.log(Order.String("apple", "apple")) // 0See
mapInputto compare objects by a string propertyStructto combine with other orders for struct comparison
Signature
declare const String: Order<string>Since v4.0.0
mapping
Section titled “mapping”mapInput
Section titled “mapInput”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.
Example (Mapping Input)
import { Order } from "effect"
const byLength = Order.mapInput(Order.Number, (s: string) => s.length)
console.log(byLength("a", "bb")) // -1console.log(byLength("bb", "a")) // 1console.log(byLength("aa", "bb")) // 0See
combineto combine mapped orders for multi-criteria comparisonStructto 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>}Since v2.0.0
predicates
Section titled “predicates”isBetween
Section titled “isBetween”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.
Example (Checking ranges)
import { Order } from "effect"
const betweenNumber = Order.isBetween(Order.Number)
console.log(betweenNumber(5, { minimum: 1, maximum: 10 })) // trueconsole.log(betweenNumber(1, { minimum: 1, maximum: 10 })) // trueconsole.log(betweenNumber(10, { minimum: 1, maximum: 10 })) // trueconsole.log(betweenNumber(0, { minimum: 1, maximum: 10 })) // falseconsole.log(betweenNumber(11, { minimum: 1, maximum: 10 })) // falseSee
clampto clamp a value to a rangeisLessThanOrEqualTofor less than or equal checkisGreaterThanOrEqualTofor greater than or equal check
Signature
declare const isBetween: <A>(O: Order<A>) => { (options: { minimum: A; maximum: A }): (self: A) => boolean (self: A, options: { minimum: A; maximum: A }): boolean}Since v4.0.0
isGreaterThan
Section titled “isGreaterThan”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.
Example (Checking greater-than comparisons)
import { Order } from "effect"
const isGreaterThanNumber = Order.isGreaterThan(Order.Number)
console.log(isGreaterThanNumber(2, 1)) // trueconsole.log(isGreaterThanNumber(1, 2)) // falseconsole.log(isGreaterThanNumber(1, 1)) // falseSee
isGreaterThanOrEqualTofor non-strict greater than or equalisLessThanfor strict less than
Signature
declare const isGreaterThan: <A>(O: Order<A>) => { (that: A): (self: A) => boolean; (self: A, that: A): boolean }Since v4.0.0
isGreaterThanOrEqualTo
Section titled “isGreaterThanOrEqualTo”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.
Example (Checking greater-than-or-equal comparisons)
import { Order } from "effect"
const isGreaterThanOrEqualToNumber = Order.isGreaterThanOrEqualTo(Order.Number)
console.log(isGreaterThanOrEqualToNumber(2, 1)) // trueconsole.log(isGreaterThanOrEqualToNumber(1, 1)) // trueconsole.log(isGreaterThanOrEqualToNumber(1, 2)) // falseSee
isGreaterThanfor strict greater thanisLessThanOrEqualTofor less than or equal
Signature
declare const isGreaterThanOrEqualTo: <A>(O: Order<A>) => { (that: A): (self: A) => boolean (self: A, that: A): boolean}Since v4.0.0
isLessThan
Section titled “isLessThan”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.
Example (Checking less-than comparisons)
import { Order } from "effect"
const isLessThanNumber = Order.isLessThan(Order.Number)
console.log(isLessThanNumber(1, 2)) // trueconsole.log(isLessThanNumber(2, 1)) // falseconsole.log(isLessThanNumber(1, 1)) // falseSee
isLessThanOrEqualTofor non-strict less than or equalisGreaterThanfor strict greater than
Signature
declare const isLessThan: <A>(O: Order<A>) => { (that: A): (self: A) => boolean; (self: A, that: A): boolean }Since v4.0.0
isLessThanOrEqualTo
Section titled “isLessThanOrEqualTo”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.
Example (Checking less-than-or-equal comparisons)
import { Order } from "effect"
const isLessThanOrEqualToNumber = Order.isLessThanOrEqualTo(Order.Number)
console.log(isLessThanOrEqualToNumber(1, 2)) // trueconsole.log(isLessThanOrEqualToNumber(1, 1)) // trueconsole.log(isLessThanOrEqualToNumber(2, 1)) // falseSee
isLessThanfor strict less thanisGreaterThanfor strict greater than
Signature
declare const isLessThanOrEqualTo: <A>(O: Order<A>) => { (that: A): (self: A) => boolean; (self: A, that: A): boolean }Since v4.0.0
type class
Section titled “type class”Order (interface)
Section titled “Order (interface)”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.
Example (Defining a custom Order)
import { Order } from "effect"
const byAge: Order.Order<{ name: string; age: number }> = (self, that) => { if (self.age < that.age) return -1 if (self.age > that.age) return 1 return 0}
const person1 = { name: "Alice", age: 30 }const person2 = { name: "Bob", age: 25 }console.log(byAge(person1, person2)) // 1See
maketo create an order from a comparison functionOrderingfor the result type of comparisons
Signature
export interface Order<in A> { (self: A, that: A): Ordering}Since v2.0.0
type lambdas
Section titled “type lambdas”OrderTypeLambda (interface)
Section titled “OrderTypeLambda (interface)”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
export interface OrderTypeLambda extends TypeLambda { readonly type: Order<this["Target"]>}Since v2.0.0
Array_
Section titled “Array_”Signature
declare const Array_: <A>(O: Order<A>) => Order<ReadonlyArray<A>>Since v4.0.0