March Docs

RRB

RRB.Vec — persistent sequence for bulk-parallel work.

v2: backed by Array (32-way trie, O(1) amortised push, O(log₃₂ n) get).

A Slice is a zero-copy window into a Vec: Slice(arr, lo, hi). chunk(v, n) creates n Slices in O(n) — the underlying Array is shared. fold(s, z, f) iterates [lo, hi) using O(1)-amortised Array.get.

Complexity summary: empty, singleton, is_empty, length O(1) get, set O(log₃₂ n) push O(1) amortised concat(l, r) O(len(r) · log₃₂(len(l)+len(r))) slice(v, lo, hi) O(1) chunk(v, n) O(n) fold(slice, z, f) O((hi-lo) · log₃₂ n) from_list, to_list, tabulate, range O(n) map, fold_left, each O(n)

Examples

  march> let v = RRB.from_list([1, 2, 3, 4, 5])
  march> RRB.length(v)
  5
  march> let s = RRB.slice(v, 1, 4)
  march> RRB.fold(s, 0, fn (acc, x) -> acc + x)
  9

Types

ptypeVecVec(a) = Vec(Array(a))#
ptypeSliceSlice(a) = Slice(Array(a), Int, Int)#

Functions

fnchunkchunk(v: Vec(a), n: Int)#

Split v into n roughly equal contiguous Slices in index order. Returns an Array of Slices. Each Slice is a zero-copy view (O(1) to create). O(n) total.

Edge cases:
- `n <= 0` is treated as 1.
- `n > length(v)` is clamped to `length(v)` (no empty slices).
- Empty `v` returns an empty Array.

## Examples

    march> let v = RRB.range(0, 6)
    march> Array.length(RRB.chunk(v, 3))
    3
fnconcatconcat(l: Vec(a), r: Vec(a)): Vec(a)#

Concatenate two Vecs: all elements of l followed by all of r. O(len(r) · log₃₂(len(l)+len(r))).

Examples

    march> RRB.to_list(RRB.concat(RRB.from_list([1,2]), RRB.from_list([3,4])))
    [1, 2, 3, 4]
fneacheach(v: Vec(a), f: a -> Unit): Unit#

Apply f to each element for side effects. O(n).

fnemptyempty(): Vec(a) do Vec(Array.empty()) end#

An empty Vec. O(1).

fnfoldfold(s: Slice(a), zero: b, f): b#

Left fold over a Slice in index order. f(acc, elem) = new_acc. O((hi-lo) · log₃₂ n).

This is the hot path inside each parallel worker: it visits only the
elements in the slice's range without copying or allocating.

## Examples

    march> let s = RRB.slice(RRB.range(0, 5), 1, 4)
    march> RRB.fold(s, 0, fn (acc, x) -> acc + x)
    6
fnfold_leftfold_left(v: Vec(a), zero: b, f): b#

Left fold over all elements. f(acc, elem) = new_acc. O(n).

Examples

    march> RRB.fold_left(RRB.from_list([1, 2, 3]), 0, fn (acc, x) -> acc + x)
    6
fnfrom_arrayfrom_array(xs: Array(a)): Vec(a) do Vec(xs) end#

Wrap an Array as a Vec. O(1).

fnfrom_listfrom_list(xs: List(a)): Vec(a) do Vec(Array.from_list(xs)) end#

Build a Vec from a list. O(n).

fngetget(v: Vec(a), i: Int): a#

Return element at 0-based index i. O(log₃₂ n). Panics if out of bounds.

Examples

    march> RRB.get(RRB.from_list([10, 20, 30]), 1)
    20
fnis_emptyis_empty(v: Vec(a)): Bool#

True when the Vec is empty. O(1).

fnlengthlength(v: Vec(a)): Int#

Number of elements. O(1).

fnmapmap(v: Vec(a), f: a -> b): Vec(b)#

Apply f to every element, collecting results in a new Vec. O(n).

For parallel map, use `Parallel.pmap` instead — this is the sequential
version.
fnpushpush(v: Vec(a), x: a): Vec(a)#

Append x at the end. Returns a new Vec. O(1) amortised.

fnrangerange(lo: Int, hi: Int): Vec(Int)#

Build a Vec of consecutive integers [lo, lo+1, …, hi-1]. O(hi-lo).

Examples

    march> RRB.to_list(RRB.range(1, 5))
    [1, 2, 3, 4]
fnsingletonsingleton(x: a): Vec(a) do Vec(Array.push(Array.empty(), x)) end#

A Vec containing exactly one element. O(1).

fnsliceslice(v: Vec(a), lo: Int, hi: Int): Slice(a)#

Create a Slice covering the half-open range [lo, hi). O(1).

Indices are clamped to [0, length(v)]; lo > hi (after clamping) yields
an empty slice.

## Examples

    march> RRB.fold(RRB.slice(RRB.range(0, 5), 1, 4), 0, fn (a, x) -> a + x)
    6
fntabulatetabulate(n: Int, f: Int -> a): Vec(a)#

Build a Vec of length n by calling f(i) for each index i ∈ [0, n). O(n).

Examples

    march> RRB.to_list(RRB.tabulate(4, fn i -> i * i))
    [0, 1, 4, 9]
fnto_arrayto_array(v: Vec(a)): Array(a)#

Return the underlying Array. O(1).

fnto_listto_list(v: Vec(a)): List(a)#

Return all elements as a list in index order. O(n).