Prelude
March Standard Library Prelude
Everything in this module is auto-imported into every March program. These are the most commonly needed functions and types.
Sections:
- Diverging (panic, todo, unreachable)
- Option helpers
- Result helpers
- List basics
- Combinators (identity, compose, flip, const)
- String helpers
Naming overlap with module-qualified APIs is intentional:
head,tail,is_nil,length,reverse,fold_left,
`filter`, `map` are all List-typed in the prelude (their
signatures fix `xs : List(a)`), so `length(xs)` always means
`List.length(xs)`. Strings have no `length` — use
`String.byte_size` / `String.codepoint_count` instead. The
absence of a generic `length` prevents silent type confusion.unwrapandunwrap_oroperate onOption(a). For Result
call `Result.unwrap` directly.New code should prefer module-qualified calls for readability; prelude names exist for short scripts and for the few cases (head, tail, length, reverse) where the unqualified name reads better. Prelude functions are called unqualified (length(xs), not Prelude.length(xs)).
Functions
Function composition: returns the function fn x -> f(g(x)) (g runs first). March has no chained call f(a)(b), so bind the result or wrap it in parentheses before calling it.
Examples
march> (compose(fn x -> x * 2, fn x -> x + 1))(3)
8
march> List.map([1, 2], compose(fn x -> x * 2, fn x -> x + 1))
[4, 6]Returns a one-argument function that always returns x, ignoring its argument.
Examples
march> List.map([1, 2, 3], const(0))
[0, 0, 0]Prints a value using its Show representation, with a trailing newline, and returns (). The same output as println.
debug(Some(3)) -- prints Some(3)Returns only the elements satisfying pred, in their original order.
Every element of the result is known to satisfy pred (an abstract refinement p, as for List.filter): with sum_pos(xs : List({Int | _ > 0})), sum_pos(filter(ys, fn y -> y > 0)) is proved.
Examples
march> filter([1, 2, 3, 4], fn x -> x > 2)
[3, 4]Flips the order of a two-argument function's arguments: the result g satisfies g(b, a) == f(a, b).
Examples
march> (flip(fn (a, b) -> a - b))(1, 10)
9Left fold over a list. Argument order: collection first, init second, callback last (uncurried-collection convention). The callback takes the accumulator first: f(acc, x).
Examples
march> fold_left([1, 2, 3], 10, fn (acc, x) -> acc - x)
4
march> fold_left([], 10, fn (acc, x) -> acc - x)
10Returns the first element of the list. Panics if empty; use List.head_opt when the list may be empty.
Examples
march> head([4, 5])
4The identity function — returns its argument unchanged.
Examples
march> identity(5)
5
march> List.filter_map([Some(1), None, Some(3)], identity)
[1, 3]Converts any value to its string representation; the same as str and to_string.
Examples
march> inspect([Some(1), None])
"[Some(1), None]"
march> inspect("hi")
"hi"Returns true if the list is empty.
Examples
march> is_nil([])
true
march> is_nil([1])
falseReturns the number of elements in the list. O(n). Lists only: for a String use String.byte_size or String.codepoint_count.
Examples
march> length([1, 2, 3])
3
march> length([])
0Applies f to every element of the list, returning the new list.
Examples
march> map([1, 2, 3], fn x -> x + 1)
[2, 3, 4]
march> map([], fn x -> x + 1)
[]Terminates the program with a runtime error carrying msg. Used for violated invariants — bugs, not expected failures; return a Result for errors a caller can handle. Propagates to the enclosing actor boundary. Typechecks as any type, so it can stand in any branch:
fn safe_div(a : Int, b : Int) : Int do
if b == 0 do panic("safe_div: zero divisor") else a / b end
endPrints any Show value followed by a newline, and returns (). Works for Int, Float, String, Bool, List, Option, Result, tuples, and any type with an explicit impl Show. A String prints without quotes.
println([1, 2]) -- prints [1, 2]
println("hi") -- prints hiReverses a list.
Examples
march> reverse([1, 2, 3])
[3, 2, 1]Short alias for to_string: the value's Show representation. Strings nested inside a list, option or tuple are shown without quotes.
Examples
march> str(42)
"42"
march> str([1, 2])
"[1, 2]"
march> str(Some(true))
"Some(true)"Returns all but the first element. Panics if empty; use List.tail_opt when the list may be empty.
Examples
march> tail([4, 5])
[5]
march> tail([4])
[]Marks code as not yet implemented: evaluating it is a runtime error carrying msg. Typechecks as any type so you can sketch a program top-down. Never valid in production.
fn parse_config(s : String) : Config do
todo("parse_config")
endAsserts that a code path is unreachable: reaching it at runtime is an error. Typechecks as any type.
match n % 2 do
0 -> "even"
1 -> "odd"
_ -> unreachable()
endExtracts the value from Some(x), panicking if None. The Option-only prelude form of Option.unwrap; for Result use Result.unwrap.
Examples
march> unwrap(Some(3))
3Returns the contained value, or default if None. Option-only; for Result use Result.unwrap_or.
Examples
march> unwrap_or(Some(1), 7)
1
march> unwrap_or(None, 7)
7Runs f with c installed as the capability its operations dispatch through, so a test can substitute an implementation:
with_cap(mock, fn _ -> code_under_test())At runtime this simply calls f — the capability is consumed by the compiler's capability-passing elaboration, which rewrites calls inside f to route through c's dictionary. Outside a --test build the elaboration does not run and this is exactly f(()).
Examples
march> with_cap(0, fn _ -> 9)
9