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 primitive type representing a single 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.
Converts a natural number to a byte modulo 256.
dec Byte.Is : [Byte, Byte.Class] Bool
Tests whether a byte matches a class.
type Bytes = Bytes
A primitive type representing a sequence of bytes.
An incremental byte buffer builder. Add chunks with .add, then finalize with .build.
type Bytes.Parser<e> = recursive either { .empty!, .ready iterative@attempt choice { .byte => Try<e, (Byte) self>, .close => Try<e, !>, .minMax(Bytes.Pattern, Bytes.Pattern) => Try<e, either { .fail self@attempt, .match(Bytes, Bytes) self, }>, .minMaxEnd(Bytes.Pattern, Bytes.Pattern) => Try<e, either { .fail self@attempt, .match(Bytes, Bytes)!, }>, .remainder => Try<e, Bytes>, }, }
A streaming byte parser, parameterized by an error type e.
Works like String.Parser but operates on raw bytes.
Cases:
.empty! — input is cleanly exhausted..ready parser — input is available, or the underlying source has failed. In the latter
case, every parser operation returns .err.Parser operations:
.close — close the parser..remainder — consume the parser and return all remaining bytes..byte — read the next byte..minMax(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, or .fail if no match (parser position unchanged)..minMaxEnd(prefix, suffix) — like .minMax, 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 => Try<e, !>, .read => Try<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 => Try<e, !>, .flush => Try<e, self>, .write(Bytes) => Try<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.Chunks : <e>[Bytes.Parser<e>] Stream<e, Bytes>
Streams a parser's remaining input one byte at a time.
dec Bytes.Close : <e>[Bytes.Parser<e>] Try<e, !>
Closes a parser, returning any source error.
dec Bytes.EmptyReader : Bytes.Reader<either {}>
Creates a Reader that is immediately empty.
dec Bytes.EndsWith : [Bytes, Bytes.Pattern] Bool
Returns .true! if a byte sequence ends with a pattern.
dec Bytes.Find : [Bytes, Bytes.Pattern] Option<Bytes>
Returns the first byte sequence matched by a pattern, if one exists.
dec Bytes.FindAndSplit : [Bytes, Bytes.Pattern] Option<(Bytes, Bytes, Bytes)!>
Returns the first match together with the bytes before and after it.
Returns the length of a byte sequence.
dec Bytes.Matches : [Bytes, Bytes.Pattern] Bool
Returns .true! if a whole byte sequence matches a pattern.
dec Bytes.Parse : [Bytes] Bytes.Parser<either {}>
Creates a byte Parser from a byte sequence.
The error type is either {} (impossible).
dec Bytes.ParseReader : <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 : <e>[[Bytes.Writer<!>] Try<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 Try<e, !> to propagate errors to the reader.
Bytes.PipeReader([w]
catch ! => .ok! in
do {
w.write("hello").try
w.close.try
} in .ok!
)
dec Bytes.ReadAll : <e>[Bytes.Reader<e>] Try<e, Bytes>
Reads all bytes from a Reader into a single Bytes value.
dec Bytes.Reader : [Bytes] Bytes.Reader<either {}>
Creates a Reader from a byte sequence. The error type is either {} (impossible).
dec Bytes.Remainder : <e>[Bytes.Parser<e>] Try<e, Bytes>
Consumes a parser and returns all remaining unparsed bytes.
Replaces non-overlapping occurrences of a byte sequence with another byte sequence.
Bytes.Replace("red blue red", "red", "green")
// = "green blue green"
dec Bytes.ReplacePattern : [Bytes, Bytes.Pattern, box [Bytes] Bytes] Bytes
Replaces non-overlapping pattern matches using a replacement function.
Bytes.ReplacePattern("a12b345", .repeat1.one.range(<<48>>, <<57>>)!, box [_] "#")
// = "a#b#"
dec Bytes.SplitBy : <e>[Bytes.Parser<e>] [Bytes] Stream<e, Bytes>
Splits a parser's remaining input on a byte separator.
dec Bytes.SplitByPattern : <e>[Bytes.Parser<e>] [Bytes.Pattern] Stream<e, Bytes>
Splits a parser's remaining input on a byte pattern.
dec Bytes.StartsWith : [Bytes, Bytes.Pattern] Bool
Returns .true! if a byte sequence starts with a pattern.
dec Bytes.TrimLeft : [Bytes, Bytes.Pattern] Bytes
Trims the given pattern once from the start of a byte sequence.
dec Bytes.TrimRight : [Bytes, Bytes.Pattern] Bytes
Trims the given pattern once from the end of a byte sequence.
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
A primitive type representing a Unicode scalar value.
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.
Converts a Unicode code point to a character. Invalid code points become the Unicode replacement character.
dec Char.Is : [Char, Char.Class] Bool
Tests whether a character matches a class.
Converts a character to lowercase.
Converts a character to uppercase.
Floating-point operations and constants.
type Float = Float
A primitive type representing a 64-bit floating point number.
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] Option<Float>
Parses a float literal or one of NaN, Inf, -Inf, Infinity, -Infinity.
Returns .none! when the string is not valid.
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
A primitive type representing an arbitrary-precision integer.
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] Option<Int>
Parses a decimal string into an integer.
Returns .none! 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.
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.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.ObjectFormat<a> = box choice { .parseObject(BoxMap.Readonly<String, Json>) => Try<!, 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] Try<Json.Error, Json>
Decodes JSON text into a materialized Json value.
dec Json.Empty : Json.ObjectFormat<!>
Parses an empty object. Ignores any fields, does not fail if fields are present.
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>] <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 .none!. Present fields must parse successfully.
dec Json.OrNull : <a>[Json.Format<a>] Json.Format<Option<a>>
Accepts JSON null as .ok .none!, otherwise parses with the given format
and wraps the result in .some.
dec Json.String : Json.Format<String>
Parses a JSON string.
dec Json.Tagged : [String] <a>[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("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>] <b>[box [a] Try<!, 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 : <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(*(
(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(box [n] n * 2)
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!
Incrementally constructs a list.
Returns .true! if the test function holds for all elements.
Short-circuits on the first .false!.
Returns .true! if the test function 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 requested number of elements from the start of a list.
Drops elements from the start while the test function returns .true!.
Pairs each element with its zero-based index.
Keeps the elements for which the test function returns .true!.
Maps each element to an optional value, keeping only the present results.
Returns the first element for which the test function returns .true!.
Maps each element to a list, then concatenates the result.
Applies a folding function 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 a mapping function to each element of a list.
{*(1, 2, 3)}->List.Map(box [n] n * 2)
// = *(2, 4, 6)
Returns the largest element, or .none! for an empty list.
Returns the smallest element, or .none! for an empty list.
Returns a list with the elements in reverse order.
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>] <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>] <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>] <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 up to the requested number of elements from the start of a list.
Takes elements from the start while the test function returns .true!.
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
A primitive type representing an arbitrary-precision natural number.
Nat.Clamp(x)(lo, hi) clamps x to the inclusive range [lo, hi].
dec Nat.FromString : [String] Option<Nat>
Parses a decimal string into a natural number.
Returns .none! 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.
Option<a> is either .some a or .none!.
.some a carries a value..none! means no value is available.type Option<a> = either { .none!, .some a, }
An optional value, either .some a or .none!.
Keeps the contained value only if it satisfies the predicate.
Transforms the contained value with a computation that may return no value.
Transforms the contained value, if present.
Converts .some value to a singleton list and .none! to an empty list.
Converts .some value to .ok value and .none! to the provided error.
type Ordering = either { .equal!, .greater!, .less!, }
The result of a comparison between two values.
Pull-based streams with fallible completion and explicit cancellation.
A stream can end successfully, end with an error, or yield one item at a time.
Consumers may stop early by calling .cancel, which lets the producer close
any underlying resource before the stream is discarded.
type Stream<e, a> = recursive either { .end Try<e, !>, .item choice { .cancel => Try<e, !>, .get => (a) self, }, }
A pull-based sequence of values of type a whose completion can fail with
an error of type e.
Cases:
.end means the stream is exhausted. Its payload is .ok! on normal
completion, or .err if the producer failed..item offers one item. The consumer must either call .get to receive
it and continue, or .cancel to stop early.Returns .ok.true! if the test function holds for every item.
Short-circuits and cancels the source on the first .false!.
Returns .ok.true! if the test function holds for at least one item.
Short-circuits and cancels the source on the first .true!.
Cancels a stream if it has not already ended, returning any cancellation or completion error.
Concatenates a list of streams into a single stream.
Skips the requested number of items and yields the rest.
Skips items while the test function returns .true!, then yields the rest.
Pairs each item with its zero-based index.
Keeps the items for which the test function returns .true!.
Maps each item to a stream, then flattens the result.
Flattens a stream of streams into a single stream.
Folds over the stream. The returned pair contains the stream completion status and the final accumulator.
Creates an infallible stream from a list.
Applies a mapping function to each item of a stream.
Applies a mapping function to the stream's error type.
Calculates the sum of all stream items.
Yields at most the requested number of items, cancelling the source if enough items were taken before it ended.
Yields items while the test function returns .true!, then cancels the source.
Collects the stream into a list, preserving any stream error.
type String = String
A primitive type representing a UTF-8 encoded string.
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 either { .empty!, .ready iterative@attempt choice { .char => Try<e, (Char) self>, .close => Try<e, !>, .minMax(String.Pattern, String.Pattern) => Try<e, either { .fail self@attempt, .match(String, String) self, }>, .minMaxEnd(String.Pattern, String.Pattern) => Try<e, either { .fail self@attempt, .match(String, String)!, }>, .remainder => Try<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.
Cases:
.empty! — input is cleanly exhausted..ready parser — input is available, or the underlying source has failed. In the latter
case, every parser operation returns .err.Parser operations:
.close — close the parser, returning any source error..remainder — consume the parser and return all remaining unparsed input..char — read the next character..minMax(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, or .fail if no match (parser position unchanged)..minMaxEnd(prefix, suffix) — like .minMax, 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.
String.Parse("Hello, world!").begin.case {
.empty! => ...
.ready r => r.minMax(.str "Hello", .str ", ").case {
.err e => ...
.ok .match(hello, comma) r => ...
.ok .fail r => ...
}
}
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.
dec String.Builder : String.Builder
Creates a new string Builder.
Splits a string into a list of Unicode characters.
dec String.Close : <e>[String.Parser<e>] Try<e, !>
Closes a parser, returning any source error.
Concatenates a list of strings into a single string.
String.Concat(*("Hello", ", ", "world!")) // = "Hello, world!"
dec String.EndsWith : [String, String.Pattern] Bool
Returns .true! if a string ends with a pattern.
dec String.Find : [String, String.Pattern] Option<String>
Returns the first substring matched by a pattern, if one exists.
dec String.FindAndSplit : [String, String.Pattern] Option<(String, String, String)!>
Returns the first match together with the text before and after it.
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>] Stream<e, String>
Splits a parser's remaining input into lines separated by \n or \r\n.
dec String.Matches : [String, String.Pattern] Bool
Returns .true! if a whole string matches a pattern.
dec String.Parse : [String] String.Parser<either {}>
Creates a Parser from a string. The error type is either {} (impossible).
dec String.ParseReader : <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, \\).
dec String.ReadAll : <e>[Bytes.Reader<e>] Try<e, String>
Reads all bytes from a Reader and decodes them into a String,
replacing invalid sequences with the Unicode replacement character.
dec String.Remainder : <e>[String.Parser<e>] Try<e, String>
Consumes a parser and returns all remaining unparsed input.
Replaces non-overlapping occurrences of a string with another string.
String.Replace("red blue red", "red", "green")
// = "green blue green"
dec String.ReplacePattern : [String, String.Pattern, box [String] String] String
Replaces non-overlapping pattern matches using a replacement function.
String.ReplacePattern("a12b345", .repeat1.one.ascii.digit!, box [_] "#")
// = "a#b#"
dec String.SplitBy : <e>[String.Parser<e>] [String] Stream<e, String>
Splits a parser's remaining input on a string separator.
dec String.SplitByPattern : <e>[String.Parser<e>] [String.Pattern] Stream<e, String>
Splits a parser's remaining input on a string pattern.
dec String.StartsWith : [String, String.Pattern] Bool
Returns .true! if a string starts with a pattern.
Converts a string to lowercase.
Converts a string to uppercase.
Trims whitespace from both ends of a string.
dec String.TrimLeft : [String, String.Pattern] String
Trims the given pattern once from the start of a string.
dec String.TrimRight : [String, String.Pattern] String
Trims the given pattern once from the end of a string.
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.Instants, durations, time zones, and civil date-times.
An Instant is a point on the timeline; a Duration is a signed span of
nanoseconds. The difference of two instants is a duration (Since), and two
instants can be ordered (Compare). A Zone maps instants to UTC offsets, and
InZone projects an instant into a Zoned civil date-time for calendar work.
A signed span of time, measured in nanoseconds.
Duration is just Int, so it supports the full integer algebra: add and
subtract durations, multiply or divide by a number, negate, and compare them.
Build durations from the unit constants, e.g. 5 * Time.Second or
2 * Time.Hour + 30 * Time.Minute.
type Time.Instant = iterative box choice { .add(Time.Duration) => self, .unixNanos => Int, }
A point on the timeline, independent of any time zone.
.unixNanos — nanoseconds since the Unix epoch (1970-01-01T00:00:00Z)..add(duration) — shift the instant by a duration, returning a new instant.Differences and ordering are the free functions Since and Compare; civil
fields come from projecting into a Zone with InZone.
type Time.Weekday = either { .friday!, .monday!, .saturday!, .sunday!, .thursday!, .tuesday!, .wednesday!, }
A day of the week.
type Time.Zone = box choice { .name => String, .offsetAt(Time.Instant) => Time.Duration, }
A time zone: a mapping from instants to UTC offsets.
.name — the zone's name (an IANA name like "Europe/Prague", or an
offset like "+02:00" for fixed zones)..offsetAt(instant) — the zone's UTC offset at the given instant, as a
duration (it can vary across the year because of daylight saving time).type Time.Zoned = iterative box choice { .addDays(Int) => self, .addMonths(Int) => self, .addYears(Int) => self, .day => Nat, .format(String) => String, .hour => Nat, .instant => Time.Instant, .minute => Nat, .month => Nat, .nanosecond => Nat, .second => Nat, .weekday => Time.Weekday, .year => Int, .zone => Time.Zone, }
An instant seen through a time zone: a civil date-time with calendar fields.
.year — the year (can be negative for years before 1 CE)..month — the month, 1 to 12..day — the day of the month, 1 to 31..hour — the hour, 0 to 23..minute — the minute, 0 to 59..second — the second, 0 to 59..nanosecond — the sub-second part, 0 to 999999999..weekday — the day of the week..zone — the time zone this date-time is in..instant — the underlying instant on the timeline..format(layout) — render using a strftime-style layout..addYears(n) — shift by whole years on the calendar, returning a new value..addMonths(n) — shift by whole months on the calendar..addDays(n) — shift by whole days on the calendar.Calendar arithmetic (.addYears / .addMonths / .addDays) respects the
zone, including daylight-saving transitions. For exact arithmetic on the
timeline use Instant.add instead.
Builds a civil date-time in a zone from its calendar fields:
At(zone, year, month, day, hour, minute, second). Returns .none! if the
fields do not denote a valid date and time.
dec Time.Compare : [Time.Instant, Time.Instant] Ordering
Orders two instants on the timeline.
dec Time.Epoch : Time.Instant
The Unix epoch, 1970-01-01T00:00:00Z.
dec Time.FromRFC3339 : [String] Option<Time.Instant>
Parses an RFC 3339 timestamp (e.g. "2024-01-01T12:00:00Z") into an instant.
dec Time.Hour : Time.Duration
One hour (60 minutes).
dec Time.Hours : [Time.Duration] Int
The whole number of hours in a duration (truncated toward zero).
dec Time.InZone : [Time.Instant, Time.Zone] Time.Zoned
Projects an instant into a time zone, yielding a civil date-time.
The system's local time zone.
dec Time.Microsecond : Time.Duration
One microsecond (1000 nanoseconds).
dec Time.Microseconds : [Time.Duration] Int
The whole number of microseconds in a duration (truncated toward zero).
dec Time.Millisecond : Time.Duration
One millisecond (1000 microseconds).
dec Time.Milliseconds : [Time.Duration] Int
The whole number of milliseconds in a duration (truncated toward zero).
dec Time.Minute : Time.Duration
One minute (60 seconds).
dec Time.Minutes : [Time.Duration] Int
The whole number of minutes in a duration (truncated toward zero).
dec Time.Nanosecond : Time.Duration
One nanosecond — the smallest representable duration.
dec Time.Nanoseconds : [Time.Duration] Int
The whole number of nanoseconds in a duration.
dec Time.Now : Time.Instant
The current instant, read from the system clock.
dec Time.Offset : [Time.Duration] Time.Zone
A fixed-offset zone, e.g. Offset(2 * Time.Hour) for +02:00.
Parses a civil date-time using a strftime-style layout:
text->Parse(layout, zone). Returns .none! if the text does not match.
dec Time.Second : Time.Duration
One second (1000 milliseconds).
dec Time.Seconds : [Time.Duration] Int
The whole number of seconds in a duration (truncated toward zero).
dec Time.Show : [Time.Duration] String
A human-readable rendering of a duration, e.g. "1h30m15s", "-2m", "0s".
dec Time.Since : [Time.Instant, Time.Instant] Time.Duration
a->Since(b) is the duration from b to a (that is, a − b).
dec Time.ToRFC3339 : [Time.Instant] String
Renders an instant as an RFC 3339 timestamp in UTC.
Coordinated Universal Time.
Looks up an IANA time zone by name, e.g. Zone("America/New_York").
Try<e, a> carries either .ok a or .err e.
.ok a means a successful result..err e means an error has occurred.type Try<e, a> = either { .err e, .ok a, }
A value that is either .ok a or .err e.
Keeps a successful value only if it satisfies the predicate, otherwise replaces it with the provided error.
Transforms the .ok value with a computation that may itself fail.
Transforms the .ok value, if present.
Transforms the .err value, if present.
Extracts the .ok branch from a Try<either {}, a>.
Converts .ok value to a singleton list and .err _ to an empty list.
Converts .ok value to .some value and .err _ to .none!.
Parsed URLs and URL construction helpers.
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.Error type for URL parsing failures.
dec Url.FromString : [String] Try<Url.Error, Url>
Parses a string into a Url.
Returns .err with an error message when the string is not a valid URL.