algo

.zn module

Functional collection utilities. Pure Zinc, no native code. import "algo". Fully generic (<T>/<T,U>/<T,K>) — the signatures below show each function's own type parameters; T/U/K are inferred at the call site, same as any other generic function (see the Generics section above).

sort_by/min_by/max_by compare via the key's own type (</>), so numeric keys sort numerically. unique/unique_by use real deep equality (==/!=), not string coercion. A call through the module (algo.filter(xs, pred)) is not yet argument-type-checked at the call site — the type checker doesn't track an imported module's exports (see docs/roadmap-to-1.0.md's Phase 2 status). algo.zn's own signatures are correct and self-consistent (its body type-checks cleanly); a caller passing the wrong argument type just won't be caught until runtime, same as before this migration.

algo.filter<T>(list: [T], pred: (T) => bool) => [T]

Keep elements where pred is true.

algo.map_fn<T, U>(list: [T], f: (T) => U) => [U]

Transform each element.

algo.reduce<T, U>(list: [T], f: (U, T) => U, init: U) => U

Left fold with accumulator init.

algo.each<T>(list: [T], f: (T))

Side-effecting iteration.

algo.find<T>(list: [T], pred: (T) => bool) => (T, bool)

First matching element; bool is false if none.

algo.find_index<T>(list: [T], pred: (T) => bool) => int

Index of first match, or -1.

algo.any<T>(list: [T], pred: (T) => bool) => bool

True if any element matches.

algo.all<T>(list: [T], pred: (T) => bool) => bool

True if all elements match.

algo.count<T>(list: [T], pred: (T) => bool) => int

Number of matching elements.

algo.zip<T, U>(a: [T], b: [U]) => [[any]]

Pair elements by index (length = shorter); the pair itself stays [any] — there's no tuple type to express a mixed T/U pair.

algo.flatten<T>(list: [[T]]) => [T]

Remove one level of nesting.

algo.take<T>(list: [T], n: int) => [T]

First n elements.

algo.drop<T>(list: [T], n: int) => [T]

All but the first n.

algo.take_while<T>(list: [T], pred: (T) => bool) => [T]

Leading run where pred holds.

algo.drop_while<T>(list: [T], pred: (T) => bool) => [T]

Skip the leading run, return the rest.

algo.chunk<T>(list: [T], n: int) => [[T]]

Split into groups of size n (last may be short).

algo.unique<T>(list: [T]) => [T]

Remove consecutive duplicates (deep value equality) — NOT a global dedup, see unique_by.

algo.unique_by<T, K>(list: [T], key_fn: (T) => K) => [T]

Remove all dups globally by extracted key — different result shape than unique, not just a custom-key version of it.

algo.group_by<T>(list: [T], key_fn: (T) => string) => [string, [T]]

Group into a map of lists.

algo.sort<T>(list: [T], cmp: (T, T) => bool) => [T]

Stable insertion sort; cmp(a,b) true means a first.

algo.sort_by<T, K>(list: [T], key_fn: (T) => K) => [T]

Sort by extracted key.

algo.min_by<T, K>(list: [T], key_fn: (T) => K) => (T, bool)

Minimum by key; bool false if empty.

algo.max_by<T, K>(list: [T], key_fn: (T) => K) => (T, bool)

Maximum by key; bool false if empty.

algo.sum(list: [any]) => int|float

Sum; int if every element is an int, float if any element is a float. Not generic — a homogeneous [T] can't express a genuinely mixed int/float list.

algo.product(list: [any]) => int|float

Product; same mixed-list reasoning as sum, not generic.

algo.reverse<T>(list: [T]) => [T]

Reversed copy.

algo.concat<T>(a: [T], b: [T]) => [T]

Concatenate two lists.

algo.intersperse<T>(list: [T], sep: T) => [T]

Insert sep between elements.

algo.window<T>(list: [T], n: int) => [[T]]

Sliding windows of size n.

On this page