dec Bench.BlackBox : [type a, a] a
Identity function intended for benchmarks.
Built-in package
Benchmarking helpers.
dec Bench.BlackBox : [type a, a] a
Identity function intended for benchmarks.
Non-linear ordered-map interface with data keys and non-linear values.
type BoxMap<k, v> = iterative box choice { .delete => [k] self, .get => [k] Option<v>, .keys => List<k>, .list => List<(k) v>, .put => [k, v] self, .size => Nat, }
A non-linear ordered map interface.
.size — get the number of entries..keys — get the keys in map order..list — get all entries as (key) value pairs..get(key) — look up a key..put(key, value) — return a map with that entry inserted or updated..delete(key) — return a map with that entry removed.Since BoxMap is non-linear, updates return another BoxMap value.
type BoxMap.Readonly<k, v> = box choice { .get => [k] Option<v>, .keys => List<k>, .list => List<(k) v>, .size => Nat, }
A read-only view of a BoxMap.
Builds a BoxMap from (key) value pairs.
If a key appears more than once, the last pair wins.
Builds an empty BoxMap.
Byte operations and byte classes.
type Byte = Byte
A class of bytes for parsers and Byte.Is.
.any! — any byte..byte b — a specific byte..range(lo, hi)! — bytes in the inclusive range [lo, hi].Returns the numeric value of a byte (0-255) as a natural number.
dec Byte.Is : [Byte, Byte.Class] Bool
Tests whether a byte matches a class.
An incremental byte buffer builder. Add chunks with .add, then finalize with .build.
type Bytes = Bytes
type Bytes.Parser<e> = recursive iterative@attempt choice { .byte => either { .byte (Byte) self, .end Result<e, !>, }, .close => Result<e, !>, .match => [Bytes.Pattern, Bytes.Pattern] either { .end Result<e, !>, .fail self@attempt, .match (Bytes, Bytes) self, }, .matchEnd => [Bytes.Pattern, Bytes.Pattern] either { .end Result<e, !>, .fail self@attempt, .match (Bytes, Bytes)!, }, .remainder => Result<e, Bytes>, }
A streaming byte parser, parameterized by an error type e.
Works like String.Parser but operates on raw bytes.
Operations:
.close — close the parser..remainder — consume the parser and return all remaining bytes..byte — read the next byte. Returns .end or .byte(b)..match(prefix, suffix) — find the leftmost split where prefix matches the left part
and suffix matches the longest possible right part. Returns .match(prefix_bytes, suffix_bytes)
on success, .fail if no match (parser position unchanged), or .end if input is empty..matchEnd(prefix, suffix) — like .match, but the suffix extends to the end of input.
Terminates the parser on success.Use .begin/.loop (from the recursive wrapper) to iterate over multiple matches.
type Bytes.Pattern = recursive either { .and List<self>, .bytes Bytes, .concat List<self>, .empty !, .max Nat, .min Nat, .non Byte.Class, .one Byte.Class, .or List<self>, .repeat self, .repeat1 self, }
A pattern for matching within byte sequences.
Atomic patterns:
.empty! — matches empty bytes..bytes b — matches literal bytes..one class — matches a single byte of the given Byte.Class..non class — matches a single byte NOT in the given Byte.Class..min n — matches at least n bytes (any)..max n — matches at most n bytes (any).Combinators:
.repeat p — matches zero or more repetitions of pattern p..repeat1 p — matches one or more repetitions of pattern p..concat ps — matches a sequence of patterns in order..and ps — matches only if all patterns match the same input..or ps — matches if any of the patterns match.type Bytes.Reader<e> = recursive choice { .close => Result<e, !>, .read => Result<e, either { .chunk (Bytes) self, .end !, }>, }
A streaming byte reader, parameterized by an error type e.
.close — close the reader and return any error..read — read the next chunk. Returns .end when exhausted,
or .chunk(bytes) with the next chunk of data.type Bytes.Writer<e> = iterative choice { .close => Result<e, !>, .flush => Result<e, self>, .write => [Bytes] Result<e, self>, }
A streaming byte writer, parameterized by an error type e.
.close — close the writer, flushing any pending data..flush — flush pending data without closing..write(bytes) — write a chunk of bytes.dec Bytes.Builder : Bytes.Builder
Creates a new byte buffer Builder.
dec Bytes.EmptyReader : Bytes.Reader<either {}>
Creates a Reader that is immediately empty.
Returns the length of a byte sequence.
dec Bytes.Parser : [Bytes] Bytes.Parser<either {}>
Creates a byte Parser from a byte sequence.
The error type is either {} (impossible).
dec Bytes.ParserFromReader : <e>[Bytes.Reader<e>] Bytes.Parser<e>
Creates a byte Parser from a Reader.
The error type matches the reader's error type.
dec Bytes.PipeReader : [type e, [Bytes.Writer<!>] Result<e, !>] Bytes.Reader<e>
Creates a Reader from a function that writes to a Writer.
The function receives a Writer<!> whose writes fail with ! if the
reader's consumer closes early, signaling the writer to stop.
The function returns Result<e, !> to propagate errors to the reader.
Bytes.PipeReader(type MyError, [w]
catch ! => .ok! in
do {
w.write("hello").try
w.close.try
} in .ok!
)
dec Bytes.Reader : [Bytes] Bytes.Reader<either {}>
Creates a Reader from a byte sequence. The error type is either {} (impossible).
Shared cells.
type Cell<a> = iterative choice { .end => ?, .split => [dual self] self, .take => (a) choice { .put => [a] self, }, }
A shared cell containing a value.
.end — release the cell..split — create another handle to the same cell..take — remove the current value and continue by choosing .put.Serves a value through a Cell.
Returns the final value when all clients are done.
Character operations and character classes.
type Char = Char
type Char.Class = either { .any !, .ascii either { .alpha !, .alphanum !, .any !, .digit !, }, .char Char, .whitespace !, }
A class of characters for parsers and Char.Is.
.any! — any character..char c — a specific character..whitespace! — any whitespace character..ascii.any! — any ASCII character..ascii.alpha! — ASCII letter (a-z, A-Z)..ascii.alphanum! — ASCII letter or digit..ascii.digit! — ASCII digit (0-9).Returns the Unicode code point of a character as a natural number.
dec Char.Is : [Char, Char.Class] Bool
Tests whether a character matches a class.
Floating-point operations and constants.
type Float = Float
Returns the absolute value.
Float.Atan2(y, x) is the two-argument arctangent of (y, x).
Rounds up toward positive infinity.
Float.Clamp(value)(lo, hi) computes Float.Max(Float.Min(value, hi), lo).
Cosine.
Euler's number.
Float.Equals(left, right, tolerance) tests whether left and right
differ by at most tolerance.
Returns .false! if any argument is NaN.
Exponential function.
Rounds down toward negative infinity.
Converts an integer to a float.
dec Float.FromString : [String] either { .err !, .ok Float, }
Parses a float literal or one of NaN, Inf, -Inf, Infinity, -Infinity.
Positive infinity.
Tests whether a float is finite.
dec Float.IsInfinite : [Float] Bool
Tests whether a float is positive or negative infinity.
Tests whether a float is NaN.
Natural logarithm.
Returns the larger input, or NaN if either input is NaN.
Returns the smaller input, or NaN if either input is NaN.
The IEEE-754 "not a number" value.
Negates a float.
Negative infinity.
Archimedes' constant.
Float.Pow(base, exponent) returns base raised to the power exponent.
Rounds to the nearest integer, ties away from zero.
Sine.
Square root.
Tangent.
Truncates a float toward zero.
Returns 0 for NaN, Inf, and NegInf.
Integer operations.
type Int = Int
Returns the absolute value of an integer as a natural number.
Int.Clamp(x)(lo, hi) clamps x to the inclusive range [lo, hi].
Int.Clamp(7)(0, 5) // = 5
Int.Clamp(-3)(0, 5) // = 0
dec Int.FromString : [String] either { .err !, .ok Int, }
Parses a decimal string into an integer.
Returns .err! when the string is not a valid integer.
Returns the larger of two integers.
Returns the smaller of two integers.
Int.Mod(x, n) returns the non-negative remainder of x modulo n.
The result is in [0, n), or 0 when n is 0.
Int.Range(lo, hi) produces the integers from lo (inclusive) to hi (exclusive).
Int.Range(0, 5) // = *(0, 1, 2, 3, 4)
JSON encoding/decoding.
Human-readable JSON parse/decode errors.
A reusable parser from a materialized Json value into a typed value.
A Format<a> exposes a single .parse operation that returns .ok value
on success or .err! on mismatch.
type Json = recursive either { .bool Bool, .list List<self>, .null !, .number Float, .object BoxMap.Readonly<String, self>, .string String, }
A materialized JSON value.
Notes:
.number uses Float..number(Float.NaN), .number(Float.Inf), or
.number(Float.NegInf) produces JSON null.BoxMap.Readonly, so duplicate
source keys and original key order are not preserved.type Json.ObjectFormat<a> = box choice { .parseObject => [BoxMap.Readonly<String, Json>] Option<a>, }
A reusable parser specialized to JSON objects.
Use Json.Object(...) to lift an ObjectFormat<a> into a full
Format<a>.
dec Json.And : <a: box>[Json.ObjectFormat<a>] <b: box>[Json.ObjectFormat<b>] Json.ObjectFormat<(b) a>
Runs two object formats against the same object and returns both results.
The result shape is (right) left, so
Json.Field("age", Json.Number)->Json.And(Json.Field("name", Json.String))
returns (String) Float.
Both object formats return non-linear values because either side may need to be discarded if the other side fails.
dec Json.Bool : Json.Format<Bool>
Parses a JSON boolean.
dec Json.Decode : [String] Result<Json.Error, Json>
Decodes JSON text into a materialized Json value.
Encodes a Json value into compact JSON text.
Tests two Json values for structural equality.
Object key order does not matter, because objects are normalized through
BoxMap.Readonly.
dec Json.Field : [String] <a>[Json.Format<a>] Json.ObjectFormat<a>
Parses a required object field with the given format.
For example, Json.Field("name", Json.String) accepts an object whose
"name" field is a JSON string.
dec Json.List : <a: box>[Json.Format<a>] Json.Format<List<a>>
Parses a JSON array with the given item format.
The item type must be non-linear because earlier parsed items may need to be discarded if a later item fails to parse.
dec Json.Literal : [Json] Json.Format<!>
Matches exactly one JSON value.
dec Json.Map : <a>[Json.Format<a>] [type b, box [a] b] Json.Format<b>
Applies a pure mapping function to a successful parse result.
Use Json.Map when parsing cannot fail once the underlying format
succeeds. Use Json.Then for fallible post-processing.
dec Json.Null : Json.Format<!>
Matches JSON null.
dec Json.Number : Json.Format<Float>
Parses a JSON number.
dec Json.Object : <a>[Json.ObjectFormat<a>] Json.Format<a>
Parses a JSON object with the given object format.
dec Json.OptionalField : [String] <a>[Json.Format<a>] Json.ObjectFormat<Option<a>>
Parses an optional object field with the given format.
Missing fields produce .ok .err!. Present fields must parse successfully.
dec Json.OrNull : <a>[Json.Format<a>] Json.Format<Option<a>>
Accepts JSON null as .ok .err!, otherwise parses with the given format
and wraps the result in .ok.
dec Json.String : Json.Format<String>
Parses a JSON string.
dec Json.Tagged : [type a, String, List<(Json) <b>(Json.ObjectFormat<b>) box [b] a>] Json.Format<a>
Parses tagged JSON objects by matching one field against literal JSON tags.
The first argument selects the field to inspect. Each branch provides a tag
literal, an object format, and a mapper into the result type. Tags are
compared with Json.Equals, so they may be strings, numbers, booleans, or
null, not just strings.
type Command = either {
.sleep Float,
.say String,
}
def CommandFormat = Json.Tagged(type Command, "operation", *(
(.string "sleep", Json.Field("seconds", Json.Number)) box [seconds] .sleep seconds,
(.string "say", Json.Field("message", Json.String)) box [message] .say message,
))
dec Json.Then : <a>[Json.Format<a>] [type b, box [a] Option<b>] Json.Format<b>
Applies a fallible post-processing step to a successful parse result.
The mapping function returns .ok value to accept the parsed result or
.err! to reject it.
dec Json.Union : [type a, List<<b>(Json.Format<b>) box [b] a>] Json.Format<a>
Tries multiple formats in order and returns the first successful result.
Each branch may parse to its own intermediate type before mapping into the shared result type.
type Answer = either {
.yes!,
.text String,
}
def AnswerFormat = Json.Union(type Answer, *(
(Json.Literal(.string "yes")) box [!] .yes!,
(Json.String) box [text] .text text,
))
Finite list types and list combinators.
let xs = *(1, 2, 3)
xs->List.Map(type Int, box [n] n * 2)
Incrementally constructs a list.
A list that ends with Result<e, !> instead of !.
Use it for streams that may finish with an error.
type List<a> = recursive either { .end !, .item (a) self, }
A finite, ordered sequence of values.
*(1, 2, 3) // syntax sugar for .item(1) .item(2) .item(3) .end!
Returns .true! if the predicate holds for all elements.
Short-circuits on the first .false!.
Returns .true! if the predicate holds for at least one element.
Short-circuits on the first .true!.
dec List.Builder : [type a] List.Builder<a>
Creates a new list Builder.
Flattens a list of lists into a single list.
Yields all items from a source list onto a destination channel, consuming the source.
Drops the first n elements of a list and returns the rest.
Keeps the elements for which the predicate returns .true!.
Applies f to each element and concatenates the resulting lists.
Applies f repeatedly to the current result and each list element, returning
the final result.
Expression syntax:
{0}->List.ForEach(*(1, 2, 3), box [sum, n] sum + n)
// = 6
Process syntax:
let console = Console.Open
console->List.ForEach(Nat.Range(1, 10), box [c, i]
c.print(`#{i}`)
)
console.close
Returns the number of elements in a list.
Applies f to each element of a list.
{*(1, 2, 3)}->List.Map(type Int, box [n] n * 2)
// = *(2, 4, 6)
Sorts a list in ascending data order. Equal keys keep their original order.
Sorts a non-linear list by an extracted data key.
Sorts a list in descending data order. Equal keys keep their original order.
dec List.SortDescBy : <a: box>[List<a>] [type k: data, box [a] k] List<a>
Sorts a non-linear list by an extracted data key in descending order.
dec List.SortLinearBy : <a>[List<a>] [type k: data, box [a] (k) a] List<a>
Sorts a linear list by a function that returns both the key and the item.
dec List.SortLinearDescBy : <a>[List<a>] [type k: data, box [a] (k) a] List<a>
Sorts a linear list by a key in descending order.
Calculates the sum of all elements in a list.
Returns the first n elements of a list.
Splits a list of pairs into a pair of lists.
Zips two lists into a list of pairs. Stops at the shorter list.
Linear ordered-map interface with data keys.
type Map<k, v> = iterative choice { .entry => [k] (Option<v>) choice { .delete => self, .put => [v] self, }, .keys => (List<k>) self, .list => List<(k) v>, .size => (Nat) self, }
A linear ordered map interface.
.size — get the number of entries while keeping the map..keys — get the keys in map order while keeping the map..list — consume the map and return its entries as (key) value pairs..entry(key) — inspect the current Option<v> for key, then choose
.put(value) or .delete.The map is linear: .list consumes it, while .size, .keys, and .entry
return a continuation for further use.
Builds a Map from (key) value pairs.
If a key appears more than once, the last pair wins.
Builds an empty Map.
Natural-number operations and iterators.
type Nat = Nat
Nat.Clamp(x)(lo, hi) clamps x to the inclusive range [lo, hi].
dec Nat.FromString : [String] either { .err !, .ok Nat, }
Parses a decimal string into a natural number.
Returns .err! when the string is not a valid non-negative integer.
Nat.Max(n, m) returns the larger of n and m.
The result is always a Nat, even though m is an Int.
Returns the smaller of two natural numbers.
Nat.Mod(m, n) is the remainder of dividing m by n.
Returns 0 when n is 0.
Nat.Range(lo, hi) produces the naturals from lo (inclusive) to hi (exclusive).
Nat.Range(0, 4) // = *(0, 1, 2, 3)
Produces n repetitions of .step, followed by .end!.
Nat.Repeat(3).begin.case {
.end! => "done",
.step next => ... next.loop,
}
dec Nat.RepeatLazy : [Nat] recursive either { .end !, .step box choice { .next => self, }, }
Like Repeat, but each .step carries a boxed continuation behind .next.
Use it when later steps might not be needed.
type Ordering = either { .equal !, .greater !, .less !, }
The result of a comparison between two values.
An incremental string builder. Add strings with .add, then finalize with .build.
String.Builder.add("Hello").add(", ").add("world!").build
// = "Hello, world!"
type String.Parser<e> = recursive iterative@attempt choice { .char => either { .char (Char) self, .end Result<e, !>, }, .close => Result<e, !>, .match => [String.Pattern, String.Pattern] either { .end Result<e, !>, .fail self@attempt, .match (String, String) self, }, .matchEnd => [String.Pattern, String.Pattern] either { .end Result<e, !>, .fail self@attempt, .match (String, String)!, }, .remainder => Result<e, String>, }
A streaming string parser, parameterized by an error type e.
The error type comes from the underlying source: either {} (impossible) when parsing
a plain string, or the reader's error type when parsing from a Bytes.Reader.
Operations:
.close — close the parser, returning any source error..remainder — consume the parser and return all remaining unparsed input..char — read the next character. Returns .end if input is exhausted,
or .char(c) with the character..match(prefix, suffix) — find the leftmost split where prefix matches the left part
and suffix matches the longest possible right part. Returns .match(prefix_str, suffix_str)
on success, .fail if no match (parser position unchanged), or .end if input is empty..matchEnd(prefix, suffix) — like .match, but the suffix extends to the end of input.
Terminates the parser on success.Use .begin/.loop (from the recursive wrapper) to iterate over multiple matches.
let r = String.Parser("Hello, world!")
r.match(.str "Hello", .str ", ").case {
.match(hello, comma) r => ...
.fail r => ...
.end _ => ...
}
type String.Pattern = recursive either { .and List<self>, .concat List<self>, .empty !, .max Nat, .min Nat, .non Char.Class, .one Char.Class, .or List<self>, .repeat self, .repeat1 self, .str String, }
A pattern for matching within strings.
Atomic patterns:
.empty! — matches the empty string..str s — matches a literal string..one class — matches a single character of the given Char.Class..non class — matches a single character NOT in the given Char.Class..min n — matches at least n characters (any)..max n — matches at most n characters (any).Combinators:
.repeat p — matches zero or more repetitions of pattern p..repeat1 p — matches one or more repetitions of pattern p..concat ps — matches a sequence of patterns in order..and ps — matches only if all patterns match the same input..or ps — matches if any of the patterns match.Common idiom: .repeat.one.any! matches any number of any characters.
type String = String
dec String.Builder : String.Builder
Creates a new string Builder.
Concatenates a list of strings into a single string.
String.Concat(*("Hello", ", ", "world!")) // = "Hello, world!"
Decodes bytes as UTF-8 into a string, replacing invalid sequences with the Unicode replacement character.
Joins a list of strings with a separator between each element.
String.Join(*("a", "b", "c"), ", ") // = "a, b, c"
dec String.Lines : <e>[String.Parser<e>] List.Fallible<e, String>
Splits a parser's remaining input into lines (separated by \n).
Returns a fallible list that may end with a source error.
dec String.Parser : [String] String.Parser<either {}>
Creates a Parser from a string. The error type is either {} (impossible).
dec String.ParserFromReader : <e>[Bytes.Reader<e>] String.Parser<e>
Creates a string Parser from a Bytes.Reader.
The error type matches the reader's error type.
Wraps a string in quotes with escape sequences (e.g. \n, \t, \\).
type Test = iterative box choice { .assert => [String, Bool] self, .done => !, .id => ([type a, a] a) self, .leak => ([type a, a] !) self, }
A test runner interface for writing tests.
.assert — check a condition with a label..done — finish the test..id — obtain the identity function (useful for testing type-generic code)..leak — obtain a function that discards any value.Parsed URLs and URL construction helpers.
Error type for URL parsing failures.
type Url = iterative box choice { .addQuery => [String, String] self, .appendPath => [String] self, .full => String, .host => String, .path => String, .protocol => String, .query => List<(String) String>, }
A URL value with inspection operations and derived updates.
.full — get the full URL string..protocol — get the scheme (e.g. "http", "https")..host — get the host, including port if present..path — get the decoded path..query — get the query parameters as a list of (key) value pairs..appendPath(segment) — append a path segment..addQuery(key, value) — add a query parameter.
.appendPath and .addQuery return updated Url values.dec Url.FromString : [String] Result<Url.Error, Url>
Parses a string into a Url.
Returns .err with an error message when the string is not a valid URL.