cmp_gleam

Package Version Hex Docs CI

A tiny, focused library for building small, composable comparators in Gleam. It intentionally avoids magic (no derives, no hidden behavior) so that comparison logic remains explicit, easy to test and easy to reason about.

Features

Why this approach?

The library favors explicitness over implicit derivation. By making comparators first-class and composable you get predictable behaviour, easier testing, and straightforward integration with normalization libraries when you need to handle real-world Unicode data.

Installation

gleam add cmp_gleam

Then import the cmp module in your code:

import cmp

Quick examples

1. Sort integers

import cmp
import gleam/list

pub fn sort_ints(xs: List(Int)) -> List(Int) {
  list.sort(xs, by: cmp.natural_int)
}

2. Sort records by a field (contramap pattern)

import cmp
import gleam/list
import gleam/string

type User {
  User(name: String, age: Int)
}

pub fn sort_by_name(users: List(User)) -> List(User) {
  let cmp_name = cmp.by(fn(u) { case u { User(name, _) -> name } }, string.compare)
  list.sort(users, by: cmp_name)
}

3. Lexicographic ordering (chain / then / lazy_then)

Combine multiple comparators to sort by primary key, then by secondary key:

let comparator = cmp.chain([
  cmp.by(fn(u) { case u { User(name, _) -> name } }, string.compare),
  cmp.by(fn(u) { case u { User(_, age) -> age } }, cmp.natural_int)
])
list.sort(users, by: comparator)

Unicode & normalization notes

Performance tip: precompute normalized keys

When sorting large lists by normalized strings, calling normalize on every comparison is expensive. Use the decorate-sort-undecorate pattern:

import gleam/list

// 1. Decorate: precompute normalized keys once
let decorated = list.map(users, fn(u) {
  let normalized_name = your_normalize_fn(u.name)
  #(u, normalized_name)
})

// 2. Sort by the precomputed key
let sorted_decorated = list.sort(decorated, by: cmp.by(fn(pair) { pair.1 }, string.compare))

// 3. Undecorate: extract the original values
let sorted_users = list.map(sorted_decorated, fn(pair) { pair.0 })

API overview

The library exports a single module cmp with the following main functions:

See the full API documentation for details.

Development

gleam test  # Run the tests
gleam build # Build the project

License

MIT License - see LICENSE file for details.

โœจ Search Document