ord

package
v2.1.13 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 17, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package ord provides the Ord type class for types that support total ordering.

Overview

An Ord represents a total ordering on a type. It extends Eq (equality) with a comparison function that returns -1, 0, or 1 to indicate less than, equal to, or greater than relationships.

The Ord interface:

type Ord[T any] interface {
    Eq[T]                    // Provides Equals(x, y T) bool
    Compare(x, y T) int      // Returns -1, 0, or 1
}

Ord laws:

  • Reflexivity: Compare(x, x) = 0
  • Antisymmetry: if Compare(x, y) <= 0 and Compare(y, x) <= 0 then x = y
  • Transitivity: if Compare(x, y) <= 0 and Compare(y, z) <= 0 then Compare(x, z) <= 0
  • Totality: Compare(x, y) <= 0 or Compare(y, x) <= 0

Basic Usage

Creating an Ord for integers:

intOrd := ord.FromStrictCompare[int]()

result := intOrd.Compare(5, 3)   // 1 (5 > 3)
result := intOrd.Compare(3, 5)   // -1 (3 < 5)
result := intOrd.Compare(5, 5)   // 0 (5 == 5)

equal := intOrd.Equals(5, 5)     // true

Creating a custom Ord:

type Person struct {
    Name string
    Age  int
}

// Order by age
personOrd := ord.MakeOrd(
    func(p1, p2 Person) int {
        if p1.Age < p2.Age {
            return -1
        } else if p1.Age > p2.Age {
            return 1
        }
        return 0
    },
    func(p1, p2 Person) bool {
        return p1.Age == p2.Age
    },
)

Creating Ord from compare function only:

stringOrd := ord.FromCompare(func(a, b string) int {
    if a < b {
        return -1
    } else if a > b {
        return 1
    }
    return 0
})
// Equals is automatically derived from Compare

Comparison Functions

Lt - Less than:

intOrd := ord.FromStrictCompare[int]()
isLessThan5 := ord.Lt(intOrd)(5)

result := isLessThan5(3)  // true
result := isLessThan5(5)  // false
result := isLessThan5(7)  // false

Leq - Less than or equal:

isAtMost5 := ord.Leq(intOrd)(5)

result := isAtMost5(3)  // true
result := isAtMost5(5)  // true
result := isAtMost5(7)  // false

Gt - Greater than:

isGreaterThan5 := ord.Gt(intOrd)(5)

result := isGreaterThan5(3)  // false
result := isGreaterThan5(5)  // false
result := isGreaterThan5(7)  // true

Geq - Greater than or equal:

isAtLeast5 := ord.Geq(intOrd)(5)

result := isAtLeast5(3)  // false
result := isAtLeast5(5)  // true
result := isAtLeast5(7)  // true

Between - Check if value is in range [low, high):

intOrd := ord.FromStrictCompare[int]()
isBetween3And7 := ord.Between(intOrd)(3, 7)

result := isBetween3And7(2)  // false
result := isBetween3And7(3)  // true
result := isBetween3And7(5)  // true
result := isBetween3And7(7)  // false
result := isBetween3And7(8)  // false

Min and Max

Min - Get the minimum of two values:

intOrd := ord.FromStrictCompare[int]()
min := ord.Min(intOrd)

result := min(5, 3)  // 3
result := min(3, 5)  // 3
result := min(5, 5)  // 5 (first argument when equal)

Max - Get the maximum of two values:

max := ord.Max(intOrd)

result := max(5, 3)  // 5
result := max(3, 5)  // 5
result := max(5, 5)  // 5 (first argument when equal)

Clamp - Restrict a value to a range:

intOrd := ord.FromStrictCompare[int]()
clamp := ord.Clamp(intOrd)(0, 100)

result := clamp(-10)  // 0 (clamped to minimum)
result := clamp(50)   // 50 (within range)
result := clamp(150)  // 100 (clamped to maximum)

Transforming Ord

Reverse - Invert the ordering:

intOrd := ord.FromStrictCompare[int]()
reversedOrd := ord.Reverse(intOrd)

result := intOrd.Compare(5, 3)         // 1 (5 > 3)
result := reversedOrd.Compare(5, 3)    // -1 (3 > 5 in reversed order)

min := ord.Min(reversedOrd)
result := min(5, 3)  // 5 (max in original order)

Contramap - Transform the input before comparing:

type Person struct {
    Name string
    Age  int
}

intOrd := ord.FromStrictCompare[int]()

// Order persons by age
personOrd := ord.Contramap(func(p Person) int {
    return p.Age
})(intOrd)

p1 := Person{Name: "Alice", Age: 30}
p2 := Person{Name: "Bob", Age: 25}

result := personOrd.Compare(p1, p2)  // 1 (30 > 25)

ToEq - Convert Ord to Eq:

intOrd := ord.FromStrictCompare[int]()
intEq := ord.ToEq(intOrd)

result := intEq.Equals(5, 5)  // true
result := intEq.Equals(5, 3)  // false

Semigroup and Monoid

Semigroup - Combine orderings (try first, then second):

type Person struct {
    LastName  string
    FirstName string
}

stringOrd := ord.FromStrictCompare[string]()

// Order by last name
byLastName := ord.Contramap(func(p Person) string {
    return p.LastName
})(stringOrd)

// Order by first name
byFirstName := ord.Contramap(func(p Person) string {
    return p.FirstName
})(stringOrd)

// Combine: order by last name, then first name
sg := ord.Semigroup[Person]()
personOrd := sg.Concat(byLastName, byFirstName)

p1 := Person{LastName: "Smith", FirstName: "Alice"}
p2 := Person{LastName: "Smith", FirstName: "Bob"}

result := personOrd.Compare(p1, p2)  // -1 (Alice < Bob)

Monoid - Semigroup with identity (always equal):

m := ord.Monoid[int]()

// Empty ordering considers everything equal
emptyOrd := m.Empty()
result := emptyOrd.Compare(5, 3)  // 0 (always equal)

// Concat with empty returns the original
intOrd := ord.FromStrictCompare[int]()
result := m.Concat(intOrd, emptyOrd)  // same as intOrd

MaxSemigroup - Semigroup that returns maximum:

intOrd := ord.FromStrictCompare[int]()
maxSg := ord.MaxSemigroup(intOrd)

result := maxSg.Concat(5, 3)  // 5
result := maxSg.Concat(3, 5)  // 5

MinSemigroup - Semigroup that returns minimum:

minSg := ord.MinSemigroup(intOrd)

result := minSg.Concat(5, 3)  // 3
result := minSg.Concat(3, 5)  // 3

Practical Examples

Sorting with custom order:

import (
    "sort"
    O "github.com/IBM/fp-go/v2/ord"
)

type Person struct {
    Name string
    Age  int
}

people := []Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 25},
    {Name: "Charlie", Age: 35},
}

intOrd := O.FromStrictCompare[int]()
personOrd := O.Contramap(func(p Person) int {
    return p.Age
})(intOrd)

sort.Slice(people, func(i, j int) bool {
    return personOrd.Compare(people[i], people[j]) < 0
})
// people is now sorted by age

Finding min/max in a slice:

import (
    A "github.com/IBM/fp-go/v2/array"
    O "github.com/IBM/fp-go/v2/ord"
)

numbers := []int{5, 2, 8, 1, 9, 3}
intOrd := O.FromStrictCompare[int]()

min := O.Min(intOrd)
max := O.Max(intOrd)

// Find minimum
minimum := A.Reduce(numbers, min, numbers[0])  // 1

// Find maximum
maximum := A.Reduce(numbers, max, numbers[0])  // 9

Multi-level sorting:

type Employee struct {
    Department string
    Name       string
    Salary     int
}

stringOrd := O.FromStrictCompare[string]()
intOrd := O.FromStrictCompare[int]()

// Order by department
byDept := O.Contramap(func(e Employee) string {
    return e.Department
})(stringOrd)

// Order by salary (descending)
bySalary := O.Reverse(O.Contramap(func(e Employee) int {
    return e.Salary
})(intOrd))

// Order by name
byName := O.Contramap(func(e Employee) string {
    return e.Name
})(stringOrd)

// Combine: dept, then salary (desc), then name
sg := O.Semigroup[Employee]()
employeeOrd := sg.Concat(sg.Concat(byDept, bySalary), byName)

Filtering with comparisons:

import (
    A "github.com/IBM/fp-go/v2/array"
    O "github.com/IBM/fp-go/v2/ord"
)

numbers := []int{1, 5, 3, 8, 2, 9, 4}
intOrd := O.FromStrictCompare[int]()

// Filter numbers greater than 5
gt5 := O.Gt(intOrd)(5)
result := A.Filter(gt5)(numbers)  // [8, 9]

// Filter numbers between 3 and 7
between3And7 := O.Between(intOrd)(3, 7)
result := A.Filter(between3And7)(numbers)  // [5, 3, 4]

Functions

Core operations:

  • MakeOrd[T any](func(T, T) int, func(T, T) bool) Ord[T] - Create Ord from compare and equals
  • FromCompare[T any](func(T, T) int) Ord[T] - Create Ord from compare (derives equals)
  • FromStrictCompare[A Ordered]() Ord[A] - Create Ord for built-in ordered types
  • ToEq[T any](Ord[T]) Eq[T] - Convert Ord to Eq

Transformations:

  • Reverse[T any](Ord[T]) Ord[T] - Invert the ordering
  • Contramap[A, B any](func(B) A) func(Ord[A]) Ord[B] - Transform input before comparing

Comparisons:

  • Lt[A any](Ord[A]) func(A) func(A) bool - Less than
  • Leq[A any](Ord[A]) func(A) func(A) bool - Less than or equal
  • Gt[A any](Ord[A]) func(A) func(A) bool - Greater than
  • Geq[A any](Ord[A]) func(A) func(A) bool - Greater than or equal
  • Between[A any](Ord[A]) func(A, A) func(A) bool - Check if in range [low, high)

Min/Max/Clamp:

  • Min[A any](Ord[A]) func(A, A) A - Get minimum of two values
  • Max[A any](Ord[A]) func(A, A) A - Get maximum of two values
  • Clamp[A any](Ord[A]) func(A, A) func(A) A - Clamp value to range

Algebraic structures:

  • Semigroup[A any]() Semigroup[Ord[A]] - Combine orderings
  • Monoid[A any]() Monoid[Ord[A]] - Semigroup with identity (always equal)
  • MaxSemigroup[A any](Ord[A]) Semigroup[A] - Semigroup returning maximum
  • MinSemigroup[A any](Ord[A]) Semigroup[A] - Semigroup returning minimum
  • eq: Equality type class (parent of Ord)
  • constraints: Type constraints for generics
  • semigroup: Associative binary operation
  • monoid: Semigroup with identity element

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Between

func Between[A any](o Ord[A]) func(A, A) func(A) bool

Between tests whether a value is between a minimum (inclusive) and a maximum (exclusive). Returns a curried function that first takes the range bounds, then takes the value to test.

The range is [lo, hi), meaning lo is included but hi is excluded.

Example:

intOrd := ord.FromStrictCompare[int]()
isBetween3And7 := ord.Between(intOrd)(3, 7)
result := isBetween3And7(2)  // false (below range)
result := isBetween3And7(3)  // true (at lower bound)
result := isBetween3And7(5)  // true (within range)
result := isBetween3And7(7)  // false (at upper bound, excluded)
result := isBetween3And7(8)  // false (above range)
Example
intOrd := FromStrictCompare[int]()
isBetween3And7 := Between(intOrd)(3, 7)

result1 := isBetween3And7(2)
result2 := isBetween3And7(3)
result3 := isBetween3And7(5)
result4 := isBetween3And7(7)
result5 := isBetween3And7(8)

println(result1) // false
println(result2) // true
println(result3) // true
println(result4) // false
println(result5) // false

func Clamp

func Clamp[A any](o Ord[A]) func(A, A) func(A) A

Clamp restricts a value to be within a specified range [low, hi]. If the value is less than low, low is returned. If the value is greater than hi, hi is returned. Otherwise, the value itself is returned.

Example:

intOrd := ord.FromStrictCompare[int]()
clamp := ord.Clamp(intOrd)(0, 100)
result := clamp(-10)  // 0
result := clamp(50)   // 50
result := clamp(150)  // 100
Example
intOrd := FromStrictCompare[int]()
clamp := Clamp(intOrd)(0, 100)

result1 := clamp(-10)
result2 := clamp(50)
result3 := clamp(150)

println(result1) // 0
println(result2) // 50
println(result3) // 100

func Geq

func Geq[A any](o Ord[A]) func(A) func(A) bool

Geq tests whether one value is greater than or equal to another. Returns a curried function that first takes the comparison value, then takes the value to test.

Example:

intOrd := ord.FromStrictCompare[int]()
isAtLeast5 := ord.Geq(intOrd)(5)
result := isAtLeast5(3)  // false
result := isAtLeast5(5)  // true
result := isAtLeast5(7)  // true
Example
intOrd := FromStrictCompare[int]()
isAtLeast5 := Geq(intOrd)(5)

result1 := isAtLeast5(3)
result2 := isAtLeast5(5)
result3 := isAtLeast5(7)

println(result1) // false
println(result2) // true
println(result3) // true

func Gt

func Gt[A any](o Ord[A]) func(A) func(A) bool

Gt tests whether one value is strictly greater than another. Returns a curried function that first takes the comparison value, then takes the value to test.

Example:

intOrd := ord.FromStrictCompare[int]()
isGreaterThan5 := ord.Gt(intOrd)(5)
result := isGreaterThan5(3)  // false
result := isGreaterThan5(5)  // false
result := isGreaterThan5(7)  // true
Example
intOrd := FromStrictCompare[int]()
isGreaterThan5 := Gt(intOrd)(5)

result1 := isGreaterThan5(3)
result2 := isGreaterThan5(5)
result3 := isGreaterThan5(7)

println(result1) // false
println(result2) // false
println(result3) // true

func Leq

func Leq[A any](o Ord[A]) func(A) func(A) bool

Leq tests whether one value is less than or equal to another. Returns a curried function that first takes the comparison value, then takes the value to test.

Example:

intOrd := ord.FromStrictCompare[int]()
isAtMost5 := ord.Leq(intOrd)(5)
result := isAtMost5(3)  // true
result := isAtMost5(5)  // true
result := isAtMost5(7)  // false
Example
intOrd := FromStrictCompare[int]()
isAtMost5 := Leq(intOrd)(5)

result1 := isAtMost5(3)
result2 := isAtMost5(5)
result3 := isAtMost5(7)

println(result1) // true
println(result2) // true
println(result3) // false

func Lt

func Lt[A any](o Ord[A]) func(A) func(A) bool

Lt tests whether one value is strictly less than another. Returns a curried function that first takes the comparison value, then takes the value to test.

Example:

intOrd := ord.FromStrictCompare[int]()
isLessThan5 := ord.Lt(intOrd)(5)
result := isLessThan5(3)  // true
result := isLessThan5(5)  // false
result := isLessThan5(7)  // false
Example
intOrd := FromStrictCompare[int]()
isLessThan5 := Lt(intOrd)(5)

result1 := isLessThan5(3)
result2 := isLessThan5(5)
result3 := isLessThan5(7)

println(result1) // true
println(result2) // false
println(result3) // false

func Max

func Max[A any](o Ord[A]) func(A, A) A

Max takes the maximum of two values according to the given ordering. If the values are considered equal, the first argument is chosen.

Example:

intOrd := ord.FromStrictCompare[int]()
max := ord.Max(intOrd)
result := max(5, 3)  // 5
result := max(5, 5)  // 5 (first argument)
Example
intOrd := FromStrictCompare[int]()
max := Max(intOrd)

result := max(5, 3)
println(result) // 5

func MaxSemigroup

func MaxSemigroup[A any](o Ord[A]) S.Semigroup[A]

MaxSemigroup returns a semigroup where Concat will return the maximum value according to the provided ordering.

Example:

intOrd := ord.FromStrictCompare[int]()
maxSg := ord.MaxSemigroup(intOrd)
result := maxSg.Concat(5, 3)  // 5
result := maxSg.Concat(3, 5)  // 5
Example
intOrd := FromStrictCompare[int]()
maxSg := MaxSemigroup(intOrd)

result := maxSg.Concat(5, 3)
println(result) // 5

func Min

func Min[A any](o Ord[A]) func(A, A) A

Min takes the minimum of two values according to the given ordering. If the values are considered equal, the first argument is chosen.

Example:

intOrd := ord.FromStrictCompare[int]()
min := ord.Min(intOrd)
result := min(5, 3)  // 3
result := min(5, 5)  // 5 (first argument)
Example
intOrd := FromStrictCompare[int]()
min := Min(intOrd)

result := min(5, 3)
println(result) // 3

func MinSemigroup

func MinSemigroup[A any](o Ord[A]) S.Semigroup[A]

MinSemigroup returns a semigroup where Concat will return the minimum value according to the provided ordering.

Example:

intOrd := ord.FromStrictCompare[int]()
minSg := ord.MinSemigroup(intOrd)
result := minSg.Concat(5, 3)  // 3
result := minSg.Concat(3, 5)  // 3
Example
intOrd := FromStrictCompare[int]()
minSg := MinSemigroup(intOrd)

result := minSg.Concat(5, 3)
println(result) // 3

func Monoid

func Monoid[A any]() M.Monoid[Ord[A]]

Monoid implements a two-level ordering with an identity element.

Properties:

  • Concat(ord1, ord2) will order first by ord1, and then by ord2
  • Empty() returns an Ord that always considers compared elements equal

The Empty ordering acts as an identity: Concat(ord, Empty()) == ord

Example:

m := ord.Monoid[int]()
emptyOrd := m.Empty()
result := emptyOrd.Compare(5, 3)  // 0 (always equal)

intOrd := ord.FromStrictCompare[int]()
combined := m.Concat(intOrd, emptyOrd)  // same as intOrd
Example
m := Monoid[int]()

// Empty ordering considers everything equal
emptyOrd := m.Empty()
result := emptyOrd.Compare(5, 3)
println(result) // 0

func Semigroup

func Semigroup[A any]() S.Semigroup[Ord[A]]

Semigroup implements a two-level ordering that combines two Ord instances. The resulting Ord will first compare using the first ordering, and only if the values are equal according to the first ordering, it will use the second ordering.

This is useful for implementing multi-level sorting (e.g., sort by last name, then by first name).

Example:

type Person struct { LastName, FirstName string }
stringOrd := ord.FromStrictCompare[string]()
byLastName := ord.Contramap(func(p Person) string { return p.LastName })(stringOrd)
byFirstName := ord.Contramap(func(p Person) string { return p.FirstName })(stringOrd)
sg := ord.Semigroup[Person]()
personOrd := sg.Concat(byLastName, byFirstName)
// Now persons are ordered by last name, then by first name
Example
type Person struct {
	LastName  string
	FirstName string
}

stringOrd := FromStrictCompare[string]()

// Order by last name
byLastName := Contramap(func(p Person) string {
	return p.LastName
})(stringOrd)

// Order by first name
byFirstName := Contramap(func(p Person) string {
	return p.FirstName
})(stringOrd)

// Combine: order by last name, then first name
sg := Semigroup[Person]()
personOrd := sg.Concat(byLastName, byFirstName)

p1 := Person{LastName: "Smith", FirstName: "Alice"}
p2 := Person{LastName: "Smith", FirstName: "Bob"}

result := personOrd.Compare(p1, p2)
println(result) // -1 (Alice < Bob)

func ToEq

func ToEq[T any](o Ord[T]) E.Eq[T]

ToEq converts an Ord to [E.Eq]. This allows using an Ord instance where only equality checking is needed.

Example:

intOrd := ord.FromStrictCompare[int]()
intEq := ord.ToEq(intOrd)
result := intEq.Equals(5, 5)  // true

Types

type Kleisli added in v2.1.8

type Kleisli[A, B any] = func(A) Ord[B]

Kleisli represents a function that takes a value of type A and returns an Ord[B]. This is useful for creating orderings that depend on input values.

Type Parameters:

  • A: The input type
  • B: The type for which ordering is produced

Example:

// Create a Kleisli that produces different orderings based on input
var orderingFactory Kleisli[string, int] = func(mode string) Ord[int] {
    if mode == "ascending" {
        return ord.FromStrictCompare[int]()
    }
    return ord.Reverse(ord.FromStrictCompare[int]())
}
ascOrd := orderingFactory("ascending")
descOrd := orderingFactory("descending")
Example

Example test for Kleisli

// Create a Kleisli that produces different orderings based on input
var orderingFactory Kleisli[string, int] = func(mode string) Ord[int] {
	if mode == "ascending" {
		return FromStrictCompare[int]()
	}
	return Reverse(FromStrictCompare[int]())
}

ascOrd := orderingFactory("ascending")
descOrd := orderingFactory("descending")

println(ascOrd.Compare(5, 3))  // 1
println(descOrd.Compare(5, 3)) // -1

type Operator added in v2.1.8

type Operator[A, B any] = Kleisli[Ord[A], B]

Operator represents a function that transforms an Ord[A] into a value of type B. This is commonly used for operations that modify or combine orderings.

Type Parameters:

  • A: The type for which ordering is defined
  • B: The result type of the operation

This is equivalent to Kleisli[Ord[A], B] and is used for operations like Contramap, which takes an Ord[A] and produces an Ord[B].

Example:

// Contramap is an Operator that transforms Ord[A] to Ord[B]
type Person struct { Age int }
var ageOperator Operator[int, Person] = ord.Contramap(func(p Person) int {
    return p.Age
})
intOrd := ord.FromStrictCompare[int]()
personOrd := ageOperator(intOrd)
Example

Example test for Operator

type Person struct {
	Name string
	Age  int
}

// Operator that transforms Ord[int] to Ord[Person] by age
var ageOperator Operator[int, Person] = Contramap(func(p Person) int {
	return p.Age
})

intOrd := FromStrictCompare[int]()
personOrd := ageOperator(intOrd)

p1 := Person{Name: "Alice", Age: 30}
p2 := Person{Name: "Bob", Age: 25}

result := personOrd.Compare(p1, p2)
println(result) // 1 (30 > 25)

func Contramap

func Contramap[A, B any](f func(B) A) Operator[A, B]

Contramap creates an ordering under a transformation function. This allows ordering values of type B by first transforming them to type A and then using the ordering for type A.

See: https://github.com/fantasyland/fantasy-land?tab=readme-ov-file#profunctor

Parameters:

  • f: A transformation function from B to A

Returns a function that takes an Ord[A] and returns an Ord[B]

Example:

type Person struct { Name string; Age int }
intOrd := ord.FromStrictCompare[int]()
personOrd := ord.Contramap(func(p Person) int {
    return p.Age
})(intOrd)
// Now persons are ordered by age
Example
type Person struct {
	Name string
	Age  int
}

intOrd := FromStrictCompare[int]()

// Order persons by age
personOrd := Contramap(func(p Person) int {
	return p.Age
})(intOrd)

p1 := Person{Name: "Alice", Age: 30}
p2 := Person{Name: "Bob", Age: 25}

result := personOrd.Compare(p1, p2)
println(result) // 1 (30 > 25)

type Ord

type Ord[T any] interface {
	E.Eq[T]
	Compare(x, y T) int
}

Ord represents a total ordering type class for type T. It extends Eq with a comparison function that establishes a total order.

Type Parameters:

  • T: The type for which ordering is defined

Methods:

  • Equals(x, y T) bool: Inherited from Eq, returns true if x and y are equal
  • Compare(x, y T) int: Returns -1 if x < y, 0 if x == y, 1 if x > y

Laws: An Ord instance must satisfy the total order laws:

  1. Reflexivity: Compare(x, x) = 0 for all x
  2. Antisymmetry: if Compare(x, y) <= 0 and Compare(y, x) <= 0 then x = y
  3. Transitivity: if Compare(x, y) <= 0 and Compare(y, z) <= 0 then Compare(x, z) <= 0
  4. Totality: Compare(x, y) <= 0 or Compare(y, x) <= 0 for all x, y

The Compare function must be consistent with Equals:

  • Compare(x, y) = 0 if and only if Equals(x, y) = true

Example:

// Using built-in ordering for integers
intOrd := ord.FromStrictCompare[int]()
result := intOrd.Compare(5, 3)   // 1 (5 > 3)
result := intOrd.Compare(3, 5)   // -1 (3 < 5)
result := intOrd.Compare(5, 5)   // 0 (5 == 5)

// Creating custom ordering
type Person struct { Name string; Age int }
personOrd := ord.MakeOrd(
    func(p1, p2 Person) int {
        if p1.Age < p2.Age { return -1 }
        if p1.Age > p2.Age { return 1 }
        return 0
    },
    func(p1, p2 Person) bool { return p1.Age == p2.Age },
)

func FromCompare

func FromCompare[T any](compare func(T, T) int) Ord[T]

FromCompare creates an instance of an Ord from a compare function. The equals function is automatically derived from the compare function.

Parameters:

  • compare: A comparison function that returns -1 if x < y, 0 if x == y, 1 if x > y

Example:

stringOrd := ord.FromCompare(func(a, b string) int {
    if a < b { return -1 }
    if a > b { return 1 }
    return 0
})
Example
stringOrd := FromCompare(func(a, b string) int {
	if a < b {
		return -1
	} else if a > b {
		return 1
	}
	return 0
})

result := stringOrd.Compare("apple", "banana")
println(result) // -1

func FromStrictCompare

func FromStrictCompare[A C.Ordered]() Ord[A]

FromStrictCompare implements the ordering based on the built-in native order for types that satisfy the Ordered constraint (integers, floats, strings).

This is the most common way to create an Ord for built-in types.

Example:

intOrd := ord.FromStrictCompare[int]()
result := intOrd.Compare(5, 3)  // 1

stringOrd := ord.FromStrictCompare[string]()
result := stringOrd.Compare("apple", "banana")  // -1
Example

Example tests for documentation

intOrd := FromStrictCompare[int]()

result1 := intOrd.Compare(5, 3)
result2 := intOrd.Compare(3, 5)
result3 := intOrd.Compare(5, 5)

println(result1) // 1
println(result2) // -1
println(result3) // 0

func MakeOrd

func MakeOrd[T any](c func(x, y T) int, e func(x, y T) bool) Ord[T]

MakeOrd creates an instance of an Ord from a compare function and an equals function.

Parameters:

  • c: A comparison function that returns -1 if x < y, 0 if x == y, 1 if x > y
  • e: An equality function that returns true if x and y are equal

The compare and equals functions must be consistent: c(x, y) == 0 iff e(x, y) == true

Example:

intOrd := ord.MakeOrd(
    func(a, b int) int {
        if a < b { return -1 }
        if a > b { return 1 }
        return 0
    },
    func(a, b int) bool { return a == b },
)
Example
type Person struct {
	Name string
	Age  int
}

personOrd := MakeOrd(
	func(p1, p2 Person) int {
		if p1.Age < p2.Age {
			return -1
		} else if p1.Age > p2.Age {
			return 1
		}
		return 0
	},
	func(p1, p2 Person) bool {
		return p1.Age == p2.Age
	},
)

p1 := Person{Name: "Alice", Age: 30}
p2 := Person{Name: "Bob", Age: 25}

result := personOrd.Compare(p1, p2)
println(result) // 1 (30 > 25)

func OrdTime added in v2.1.1

func OrdTime() Ord[time.Time]

OrdTime returns an Ord instance for time.Time values. Times are ordered chronologically using the Before and After methods.

Example:

timeOrd := ord.OrdTime()
t1 := time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)
t2 := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
result := timeOrd.Compare(t1, t2)  // -1 (t1 is before t2)
Example
timeOrd := OrdTime()

t1 := time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)
t2 := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)

result := timeOrd.Compare(t1, t2)
println(result) // -1 (t1 is before t2)

func Reverse

func Reverse[T any](o Ord[T]) Ord[T]

Reverse creates an inverted ordering where the comparison results are reversed. If the original ordering has x < y, the reversed ordering will have x > y.

Example:

intOrd := ord.FromStrictCompare[int]()
reversedOrd := ord.Reverse(intOrd)
result := reversedOrd.Compare(5, 3)  // -1 (reversed from 1)
Example
intOrd := FromStrictCompare[int]()
reversedOrd := Reverse(intOrd)

result1 := intOrd.Compare(5, 3)
result2 := reversedOrd.Compare(5, 3)

println(result1) // 1
println(result2) // -1

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL