View Source Funx.Ord.Utils (funx v0.1.0)

Utility functions for working with the Funx.Ord protocol. These functions assume that types passed in either support Elixir's comparison operators or implement the Funx.Ord protocol.

Summary

Functions

Appends two Ord instances, combining their comparison logic.

Checks if value is between min and max, inclusive, with an optional custom Ord.

Clamps a value between min and max, with an optional custom Ord.

Creates a comparator function from the given Ord module, returning true if a is less than or equal to b according to the module’s ordering.

Compares two values and returns :lt, :eq, or :gt, with an optional custom Ord.

Concatenates a list of Ord instances into a single composite comparator.

Transforms an ordering by applying a function f to values before comparison.

Returns the maximum of two values, with an optional custom Ord.

Returns the minimum of two values, with an optional custom Ord.

Reverses the ordering logic.

Converts an Ord instance into an equality comparator.

Types

@type ord_map() :: %{
  lt?: (any(), any() -> boolean()),
  le?: (any(), any() -> boolean()),
  gt?: (any(), any() -> boolean()),
  ge?: (any(), any() -> boolean())
}
@type ord_t() :: Funx.Ord.t() | ord_map()

Functions

Appends two Ord instances, combining their comparison logic.

If the first Ord comparator determines an order, that result is used. If not, the second comparator is used as a fallback.

Examples

iex> ord1 = Funx.Ord.Utils.contramap(& &1.age, Funx.Ord.Any)
iex> ord2 = Funx.Ord.Utils.contramap(& &1.name, Funx.Ord.Any)
iex> combined = Funx.Ord.Utils.append(ord1, ord2)
iex> combined.lt?.(%{age: 30, name: "Alice"}, %{age: 30, name: "Bob"})
true
Link to this function

between(value, min, max, ord \\ Ord)

View Source
@spec between(a, a, a, ord_t()) :: boolean() when a: any()

Checks if value is between min and max, inclusive, with an optional custom Ord.

Examples

iex> Funx.Ord.Utils.between(5, 1, 10)
true

iex> Funx.Ord.Utils.between(0, 1, 10)
false

iex> Funx.Ord.Utils.between(11, 1, 10)
false
Link to this function

clamp(value, min, max, ord \\ Ord)

View Source
@spec clamp(a, a, a, ord_t()) :: a when a: any()

Clamps a value between min and max, with an optional custom Ord.

Examples

iex> Funx.Ord.Utils.clamp(5, 1, 10)
5

iex> Funx.Ord.Utils.clamp(0, 1, 10)
1

iex> Funx.Ord.Utils.clamp(15, 1, 10)
10
@spec comparator(ord_t()) :: (any(), any() -> boolean())

Creates a comparator function from the given Ord module, returning true if a is less than or equal to b according to the module’s ordering.

Useful for sorting with Enum.sort/2 or similar functions.

Examples

iex> comparator = Funx.Ord.Utils.comparator(Funx.Ord.Any)
iex> Enum.sort([3, 1, 2], comparator)
[1, 2, 3]
Link to this function

compare(a, b, ord \\ Ord)

View Source
@spec compare(a, a, ord_t()) :: :lt | :eq | :gt when a: any()

Compares two values and returns :lt, :eq, or :gt, with an optional custom Ord.

Examples

iex> Funx.Ord.Utils.compare(3, 5)
:lt

iex> Funx.Ord.Utils.compare(7, 7)
:eq

iex> Funx.Ord.Utils.compare(9, 4)
:gt
@spec concat([Funx.Monoid.Ord.t()]) :: Funx.Monoid.Ord.t()

Concatenates a list of Ord instances into a single composite comparator.

This function reduces a list of Ord comparators into a single Ord, applying them in sequence until an order is determined.

Examples

iex> ord_list = [
...>   Funx.Ord.Utils.contramap(& &1.age, Funx.Ord.Any),
...>   Funx.Ord.Utils.contramap(& &1.name, Funx.Ord.Any)
...> ]
iex> combined = Funx.Ord.Utils.concat(ord_list)
iex> combined.gt?.(%{age: 25, name: "Charlie"}, %{age: 25, name: "Bob"})
true
Link to this function

contramap(f, ord \\ Ord)

View Source
@spec contramap((a -> b), ord_t()) :: ord_map() when a: any(), b: any()

Transforms an ordering by applying a function f to values before comparison.

The ord parameter can be an Ord module or a custom comparator map with comparison functions (:lt?, :le?, :gt?, and :ge?). When an Ord module is provided, it wraps the module’s functions to apply f to each value before invoking the comparison. If a custom comparator map is provided, it wraps the functions in the map to apply f to each value.

Examples

iex> ord = Funx.Ord.Utils.contramap(&String.length/1, Funx.Ord.Any)
iex> ord.lt?.("cat", "zebra")
true
@spec max(a, a, ord_t()) :: a when a: any()

Returns the maximum of two values, with an optional custom Ord.

Examples

iex> Funx.Ord.Utils.max(3, 5)
5

iex> ord = Funx.Ord.Utils.contramap(&String.length/1, Funx.Ord.Any)
iex> Funx.Ord.Utils.max("cat", "zebra", ord)
"zebra"
@spec min(a, a, ord_t()) :: a when a: any()

Returns the minimum of two values, with an optional custom Ord.

Examples

iex> Funx.Ord.Utils.min(10, 7)
7

iex> ord = Funx.Ord.Utils.contramap(&String.length/1, Funx.Ord.Any)
iex> Funx.Ord.Utils.min("apple", "kiwi", ord)
"kiwi"
@spec reverse(ord_t()) :: ord_map()

Reverses the ordering logic.

Examples

iex> ord = Funx.Ord.Utils.reverse(Funx.Ord.Any)
iex> ord.lt?.(10, 5)
true
@spec to_eq(ord_t()) :: Funx.Eq.Utils.eq_map()

Converts an Ord instance into an equality comparator.

This function creates a map containing two functions:

  • eq?/2: Returns true if a and b are considered equal by the given Ord.
  • not_eq?/2: Returns true if a and b are not considered equal by the given Ord.

Examples

iex> eq = Funx.Ord.Utils.to_eq(Funx.Ord.Any)
iex> eq.eq?.(5, 5)
true