## Full Docs per Module
### Str

Utf8Problem : [ InvalidStartByte, UnexpectedEndOfSequence, ExpectedContinuation, OverlongEncoding, CodepointTooLarge, EncodesSurrogateHalf ]

is_empty : Str -> Bool

Description:
Returns [Bool.true] if the string is empty, and [Bool.false] otherwise.
```roc
expect Str.is_empty("hi!") == Bool.false
expect Str.is_empty("") == Bool.true
```

concat : Str, Str -> Str

Description:
Concatenates two strings together.
```roc
expect Str.concat("ab", "cd") == "abcd"
expect Str.concat("hello", "") == "hello"
expect Str.concat("", "") == ""
```

with_capacity : U64 -> Str

Description:
Returns an empty string with the specified capacity pre-allocated. Use when building strings incrementally with [Str.concat] to avoid reallocations. Prefer over `""` when concatenating. See [Str.reserve] for existing strings.
```roc
Str.with_capacity(45) |> Str.concat("Hello") |> Str.concat(", World!")
```

reserve : Str, U64 -> Str

Description:
Increases a string's capacity by at least the given number of additional bytes, preventing reallocations during subsequent [Str.concat] calls. For empty strings, use [Str.with_capacity] instead.
```roc
greeting |> Str.reserve(21) |> Str.concat(", ") |> Str.concat(subject) |> Str.concat("!")
```

join_with : List Str, Str -> Str

Description:
Combines a [List] of strings into a single string, with a separator
string in between each.
```roc
expect Str.join_with(["one", "two", "three"], ", ") == "one, two, three"
expect Str.join_with(["1", "2", "3", "4"], ".") == "1.2.3.4"
```

split_on : Str, Str -> List Str

Description:
Split a string around a separator.

Passing `""` for the separator is not useful;
it returns the original string wrapped in a [List].
```roc
expect Str.split_on("1,2,3", ",") == ["1","2","3"]
expect Str.split_on("1,2,3", "") == ["1,2,3"]
```

repeat : Str, U64 -> Str

Description:
Repeats a string the given number of times.
```roc
expect Str.repeat("z", 3) == "zzz"
expect Str.repeat("na", 8) == "nananananananana"
```
Returns `""` when given `""` for the string or `0` for the count.
```roc
expect Str.repeat("", 10) == ""
expect Str.repeat("anything", 0) == ""
```

len : Str -> [LearnAboutStringsInRoc Str]

Description:
A stub function to help people discover [how they should handle this in Roc](https://www.roc-lang.org/faq.html#strings-in-roc).

to_utf8 : Str -> List U8

Description:
Returns a [List] of the string's [U8] UTF-8 [code units](https://unicode.org/glossary/#code_unit).
(To split the string into a [List] of smaller [Str] values instead of [U8] values,
see [Str.split_on].)
```roc
expect Str.to_utf8("Roc") == [82, 111, 99]
expect Str.to_utf8("鹏") == [233, 185, 143]
expect Str.to_utf8("சி") == [224, 174, 154, 224, 174, 191]
expect Str.to_utf8("🐦") == [240, 159, 144, 166]
```

from_utf8 : List U8 -> Result Str [ BadUtf8 { problem : Utf8Problem, index : U64 } ]

Description:
Converts a [List] of [U8] UTF-8 [code units](https://unicode.org/glossary/#code_unit) to a string.

Returns `Err` if the given bytes are invalid UTF-8, and returns `Ok ""` when given `[]`.
```roc
expect Str.from_utf8([82, 111, 99]) == Ok("Roc")
expect Str.from_utf8([233, 185, 143]) == Ok("鹏")
expect Str.from_utf8([224, 174, 154, 224, 174, 191]) == Ok("சி")
expect Str.from_utf8([240, 159, 144, 166]) == Ok("🐦")
expect Str.from_utf8([]) == Ok("")
expect Str.from_utf8([255]) |> Result.is_err
```

from_utf8_lossy : List U8 -> Str

Description:
Converts a [List] of [U8] UTF-8 [code units](https://unicode.org/glossary/#code_unit) to a string.
Any grouping of invalid byte sequences are replaced with a single unicode replacement character '�'.

An invalid byte sequence is defined as
- a 2-byte-sequence starting byte, followed by less than 1 continuation byte
- a 3-byte-sequence starting byte, followed by less than 2 continuation bytes
- a 4-byte-sequence starting byte, followed by less than 3 continuation bytes
- an invalid codepoint from the surrogate pair block
- an invalid codepoint greater than 0x110000 encoded as a 4-byte sequence
- any valid codepoint encoded as an incorrect sequence, for instance a codepoint that should be a 2-byte sequence encoded as a 3- or 4-byte sequence

```roc
expect (Str.from_utf8_lossy [82, 111, 99, 240, 159, 144, 166]) == "Roc🐦"
expect (Str.from_utf8_lossy [82, 255, 99]) == "R�c"
expect (Str.from_utf8_lossy [82, 0xED, 0xA0, 0xBD, 99]) == "R�c"
```

from_utf16 : List U16 -> Result Str [ BadUtf16 { problem : Utf8Problem, index : U64 } ]

Description:
Converts a [List] of [U16] UTF-16 (little-endian) [code units](https://unicode.org/glossary/#code_unit) to a string.

```roc
expect Str.from_utf16([82, 111, 99]) == Ok("Roc")
expect Str.from_utf16([0xb9a, 0xbbf]) == Ok("சி")
expect Str.from_utf16([0xd83d, 0xdc26]) == Ok("🐦")
expect Str.from_utf16([]) == Ok("")
# unpaired surrogates, first and second halves
expect Str.from_utf16([82, 0xd83d, 99]) |> Result.is_err
expect Str.from_utf16([82, 0xdc96, 99]) |> Result.is_err
```

from_utf16_lossy : List U16 -> Str

Description:
Converts a [List] of [U16] UTF-16 (little-endian) [code units](https://unicode.org/glossary/#code_unit) to a string.
Any unpaired surrogate code unit is replaced with a single unicode replacement character '�'.

```roc
expect Str.from_utf16_lossy([82, 111, 99, 0xd83d, 0xdc26]) == "Roc🐦"
expect Str.from_utf16_lossy([82, 0xdc96, 99]) == "R�c"
```

from_utf32 : List U32 -> Result Str [ BadUtf32 { problem : Utf8Problem, index : U64 } ]

from_utf32_lossy : List U32 -> Str

Description:
Converts a [List] of [U32] UTF-32 [code units](https://unicode.org/glossary/#code_unit) to a string.
Any invalid code points are replaced with a single unicode replacement character '�'.
```roc
expect Str.from_utf32_lossy([82, 111, 99, 0x1f426]) == "Roc🐦"
expect Str.from_utf32_lossy([82, 0x110000, 99]) == "R�c"
```

starts_with : Str, Str -> Bool

Description:
Check if the given [Str] starts with a value.
```roc
expect Str.starts_with("ABC", "A") == Bool.true
expect Str.starts_with("ABC", "X") == Bool.false
```

ends_with : Str, Str -> Bool

Description:
Check if the given [Str] ends with a value.
```roc
expect Str.ends_with("ABC", "C") == Bool.true
expect Str.ends_with("ABC", "X") == Bool.false
```

trim : Str -> Str

Description:
Return the [Str] with all whitespace removed from both the beginning
as well as the end.
```roc
expect Str.trim("   Hello      \n\n") == "Hello"
```

trim_start : Str -> Str

Description:
Return the [Str] with all whitespace removed from the beginning.
```roc
expect Str.trim_start("   Hello      \n\n") == "Hello      \n\n"
```

trim_end : Str -> Str

Description:
Return the [Str] with all whitespace removed from the end.
```roc
expect Str.trim_end("   Hello      \n\n") == "   Hello"
```

to_dec : Str -> Result Dec [InvalidNumStr]

Description:
Encode a [Str] to a [Dec]. A [Dec] value is a 128-bit decimal
[fixed-point number](https://en.wikipedia.org/wiki/Fixed-point_arithmetic).
```roc
expect Str.to_dec("10") == Ok(10dec)
expect Str.to_dec("-0.25") == Ok(-0.25dec)
expect Str.to_dec("not a number") == Err(InvalidNumStr)
```

to_f64 : Str -> Result F64 [InvalidNumStr]

Description:
Encode a [Str] to a [F64]. A [F64] value is a 64-bit
[floating-point number](https://en.wikipedia.org/wiki/IEEE_754) and can be
specified with a `f64` suffix.
```roc
expect Str.to_f64("0.10") == Ok(0.10f64)
expect Str.to_f64("not a number") == Err(InvalidNumStr)
```

to_f32 : Str -> Result F32 [InvalidNumStr]

Description:
Encode a [Str] to a [F32].A [F32] value is a 32-bit
[floating-point number](https://en.wikipedia.org/wiki/IEEE_754) and can be
specified with a `f32` suffix.
```roc
expect Str.to_f32("0.10") == Ok(0.10f32)
expect Str.to_f32("not a number") == Err(InvalidNumStr)
```

to_u128 : Str -> Result U128 [InvalidNumStr]

Description:
Encode a [Str] to an unsigned [U128] integer. A [U128] value can hold numbers
from `0` to `340_282_366_920_938_463_463_374_607_431_768_211_455` (over
340 undecillion). It can be specified with a u128 suffix.
```roc
expect Str.to_u128("1500") == Ok(1500u128)
expect Str.to_u128("0.1") == Err(InvalidNumStr)
expect Str.to_u128("-1") == Err(InvalidNumStr)
expect Str.to_u128("not a number") == Err(InvalidNumStr)
```

to_i128 : Str -> Result I128 [InvalidNumStr]

Description:
Encode a [Str] to a signed [I128] integer. A [I128] value can hold numbers
from `-170_141_183_460_469_231_731_687_303_715_884_105_728` to
`170_141_183_460_469_231_731_687_303_715_884_105_727`. It can be specified
with a i128 suffix.
```roc
expect Str.to_u128("1500") == Ok(1500i128)
expect Str.to_i128("-1") == Ok(-1i128)
expect Str.to_i128("0.1") == Err(InvalidNumStr)
expect Str.to_i128("not a number") == Err(InvalidNumStr)
```

to_u64 : Str -> Result U64 [InvalidNumStr]

Description:
Encode a [Str] to an unsigned [U64] integer. A [U64] value can hold numbers
from `0` to `18_446_744_073_709_551_615` (over 18 quintillion). It
can be specified with a u64 suffix.
```roc
expect Str.to_u64("1500") == Ok(1500u64)
expect Str.to_u64("0.1") == Err(InvalidNumStr)
expect Str.to_u64("-1") == Err(InvalidNumStr)
expect Str.to_u64("not a number") == Err(InvalidNumStr)
```

to_i64 : Str -> Result I64 [InvalidNumStr]

Description:
Encode a [Str] to a signed [I64] integer. A [I64] value can hold numbers
from `-9_223_372_036_854_775_808` to `9_223_372_036_854_775_807`. It can be
specified with a i64 suffix.
```roc
expect Str.to_i64("1500") == Ok(1500i64)
expect Str.to_i64("-1") == Ok(-1i64)
expect Str.to_i64("0.1") == Err(InvalidNumStr)
expect Str.to_i64("not a number") == Err(InvalidNumStr)
```

to_u32 : Str -> Result U32 [InvalidNumStr]

Description:
Encode a [Str] to an unsigned [U32] integer. A [U32] value can hold numbers
from `0` to `4_294_967_295` (over 4 billion). It can be specified with
a u32 suffix.
```roc
expect Str.to_u32("1500") == Ok(1500u32)
expect Str.to_u32("0.1") == Err(InvalidNumStr)
expect Str.to_u32("-1") == Err(InvalidNumStr)
expect Str.to_u32("not a number") == Err(InvalidNumStr)
```

to_i32 : Str -> Result I32 [InvalidNumStr]

Description:
Encode a [Str] to a signed [I32] integer. A [I32] value can hold numbers
from `-2_147_483_648` to `2_147_483_647`. It can be
specified with a i32 suffix.
```roc
expect Str.to_i32("1500") == Ok(1500i32)
expect Str.to_i32("-1") == Ok(-1i32)
expect Str.to_i32("0.1") == Err(InvalidNumStr)
expect Str.to_i32("not a number") == Err(InvalidNumStr)
```

to_u16 : Str -> Result U16 [InvalidNumStr]

Description:
Encode a [Str] to an unsigned [U16] integer. A [U16] value can hold numbers
from `0` to `65_535`. It can be specified with a u16 suffix.
```roc
expect Str.to_u16("1500") == Ok(1500u16)
expect Str.to_u16("0.1") == Err(InvalidNumStr)
expect Str.to_u16("-1") == Err(InvalidNumStr)
expect Str.to_u16("not a number") == Err(InvalidNumStr)
```

to_i16 : Str -> Result I16 [InvalidNumStr]

Description:
Encode a [Str] to a signed [I16] integer. A [I16] value can hold numbers
from `-32_768` to `32_767`. It can be
specified with a i16 suffix.
```roc
expect Str.to_i16("1500") == Ok(1500i16)
expect Str.to_i16("-1") == Ok(-1i16)
expect Str.to_i16("0.1") == Err(InvalidNumStr)
expect Str.to_i16("not a number") == Err(InvalidNumStr)
```

to_u8 : Str -> Result U8 [InvalidNumStr]

Description:
Encode a [Str] to an unsigned [U8] integer. A [U8] value can hold numbers
from `0` to `255`. It can be specified with a u8 suffix.
```roc
expect Str.to_u8("250") == Ok(250u8)
expect Str.to_u8("-0.1") == Err(InvalidNumStr)
expect Str.to_u8("not a number") == Err(InvalidNumStr)
expect Str.to_u8("1500") == Err(InvalidNumStr)
```

to_i8 : Str -> Result I8 [InvalidNumStr]

Description:
Encode a [Str] to a signed [I8] integer. A [I8] value can hold numbers
from `-128` to `127`. It can be
specified with a i8 suffix.
```roc
expect Str.to_i8("-15") == Ok(-15i8)
expect Str.to_i8("150.00") == Err(InvalidNumStr)
expect Str.to_i8("not a number") == Err(InvalidNumStr)
```

count_utf8_bytes : Str -> U64

Description:
Gives the number of bytes in a [Str] value.
```roc
expect Str.count_utf8_bytes("Hello World") == 11
```

replace_each : Str, Str, Str -> Str

Description:
Returns the given [Str] with each occurrence of a substring replaced.
If the substring is not found, returns the original string.

```roc
expect Str.replace_each("foo/bar/baz", "/", "_") == "foo_bar_baz"
expect Str.replace_each("not here", "/", "_") == "not here"
```

replace_first : Str, Str, Str -> Str

Description:
Returns the given [Str] with the first occurrence of a substring replaced.
If the substring is not found, returns the original string.

```roc
expect Str.replace_first("foo/bar/baz", "/", "_") == "foo_bar/baz"
expect Str.replace_first("no slashes here", "/", "_") == "no slashes here"
```

replace_last : Str, Str, Str -> Str

Description:
Returns the given [Str] with the last occurrence of a substring replaced.
If the substring is not found, returns the original string.

```roc
expect Str.replace_last("foo/bar/baz", "/", "_") == "foo/bar_baz"
expect Str.replace_last("no slashes here", "/", "_") == "no slashes here"
```

split_first : Str, Str -> Result { before : Str, after : Str } [NotFound]

Description:
Returns the given [Str] before the first occurrence of a [delimiter](https://www.computerhope.com/jargon/d/delimite.htm), as well
as the rest of the string after that occurrence.
Returns [Err NotFound] if the delimiter is not found.
```roc
expect Str.split_first("foo/bar/baz", "/") == Ok({ before: "foo", after: "bar/baz" })
expect Str.split_first("no slashes here", "/") == Err(NotFound)
```

split_last : Str, Str -> Result { before : Str, after : Str } [NotFound]

Description:
Returns the given [Str] before the last occurrence of a delimiter, as well as
the rest of the string after that occurrence.
Returns [Err NotFound] if the delimiter is not found.
```roc
expect Str.split_last("foo/bar/baz", "/") == Ok({ before: "foo/bar", after: "baz" })
expect Str.split_last("no slashes here", "/") == Err(NotFound)
```

walk_utf8_with_index : Str, state, (state, U8, U64 -> state) -> state

Description:
Walks over the `UTF-8` bytes of the given [Str] and calls a function to update
state for each byte. The index for that byte in the string is provided
to the update function.
```roc
f : List U8, U8, U64 -> List U8
f = \state, byte, _ -> List.append(state, byte)
expect Str.walk_utf8_with_index("ABC", [], f) == [65, 66, 67]
```

walk_utf8 : Str, state, (state, U8 -> state) -> state

Description:
Walks over the `UTF-8` bytes of the given [Str] and calls a function to update
state for each byte.

```roc
sum_of_utf8_bytes =
    Str.walk_utf8("Hello, World!", 0, (\total, byte ->
        total + byte
    ))

expect sum_of_utf8_bytes == 105
```

release_excess_capacity : Str -> Str

Description:
Shrink the memory footprint of a str such that its capacity and length are equal.
Note: This will also convert seamless slices to regular lists.

with_prefix : Str, Str -> Str

Description:
Adds a prefix to the given [Str].
```roc
expect Str.with_prefix("Awesome", "Roc") == "RocAwesome"
```

contains : Str, Str -> Bool

Description:
Determines whether or not the first Str contains the second.
```roc
expect Str.contains("foobarbaz", "bar")
expect !Str.contains("apple", "orange")
expect Str.contains("anything", "")
```

drop_prefix : Str, Str -> Str

Description:
Drops the given prefix [Str] from the start of a [Str]
If the prefix is not found, returns the original string.

```roc
expect Str.drop_prefix("bar", "foo") == "bar"
expect Str.drop_prefix("foobar", "foo") == "bar"
```

drop_suffix : Str, Str -> Str

Description:
Drops the given suffix [Str] from the end of a [Str]
If the suffix is not found, returns the original string.

```roc
expect Str.drop_suffix("bar", "foo") == "bar"
expect Str.drop_suffix("barfoo", "foo") == "bar"
```

with_ascii_lowercased : Str -> Str

Description:
Lowercases ASCII characters only; non-ASCII left unchanged. For Unicode capitalization, use the `unicode` package. See [Str.caseless_ascii_equals] for case-insensitive comparison.
```roc
expect Str.with_ascii_lowercased("CAFÉ") == "cafÉ"
```

with_ascii_uppercased : Str -> Str

Description:
Uppercases ASCII characters only; non-ASCII left unchanged. For Unicode capitalization, use the `unicode` package. See [Str.caseless_ascii_equals] for case-insensitive comparison.
```roc
expect Str.with_ascii_uppercased("café") == "CAFé"
```

caseless_ascii_equals : Str, Str -> Bool

Description:
Case-insensitive comparison for ASCII characters only; non-ASCII must match exactly. See [Str.with_ascii_uppercased] and [Str.with_ascii_lowercased] for conversion.
```roc
expect Str.caseless_ascii_equals("café", "CAFé")
expect !Str.caseless_ascii_equals("café", "CAFÉ")  # é ≠ É (non-ASCII)
```

### Num

`Num a` represents either an [Int] or [Frac]. Aliases: `Int a = Num (Integer a)`, `Frac a = Num (Fraction a)`.

Untyped literals default to [I64] (integers) or [Dec] (decimals). Use suffixes for specific types: `215u8`, `76.4f32`, `123.45dec`.

## Int Types

Signed ([I8]-[I128]) can be negative; unsigned ([U8]-[U128]) cannot. Overflow crashes.

| Type | Bytes | Range |
|------|-------|-------|
| I8/U8 | 1 | -128..127 / 0..255 |
| I16/U16 | 2 | -32768..32767 / 0..65535 |
| I32/U32 | 4 | ±2.1B / 0..4.3B |
| I64/U64 | 8 | ±9.2×10¹⁸ / 0..1.8×10¹⁹ |
| I128/U128 | 16 | ±1.7×10³⁸ / 0..3.4×10³⁸ |

## Frac Types

- [Dec]: 128-bit fixed-point, 18 decimal places. `0.1 + 0.2 == 0.3` (precise). Default for decimals.
- [F32]/[F64]: Floating-point. Faster but imprecise: `0.1f64 + 0.2 != 0.3`. Has infinity/NaN.

Special float values (IEEE-754): ∞ (pos/0.0), -∞ (neg/0.0), NaN (0.0/0.0). Check with #is_nan, #is_finite, #is_infinite.

**Performance**: Dec add/sub similar to F64; Dec mul ~15x slower, div ~55x slower, trig ~2-4x slower. Use F64/F32 for performance-critical graphics/trig.

e : Frac *

Description:
Euler's number (e)

pi : Frac *

Description:
Archimedes' constant (π)

tau : Frac *

Description:
Circle constant (τ)

to_str : Num * -> Str

Description:
Convert a number to a [Str].

```roc
Num.to_str(42)
```
Only [Frac] values will include a decimal point, and they will always include one.
```roc
Num.to_str(4.2)
Num.to_str(4.0)
```
When this function is given a non-[finite](Num#is_finite)
[F64] or [F32] value, the returned string will be `"NaN"`, `"∞"`, or `"-∞"`.


int_cast : Int a -> Int b

Description:
Convert an [Int] to a new [Int] of the expected type:

```roc
# Casts a U8 to a U16
x : U16
x = Num.int_cast(255u8)
```

In the case of downsizing, information is lost:

```roc
# returns 0, as the bits were truncated.
x : U8
x = Num.int_cast(256u16)
```


compare : Num a, Num a -> [ LT, EQ, GT ]

is_lt : Num a, Num a -> Bool

Description:
Returns `Bool.true` if the first number is less than the second.

`a < b` is shorthand for `Num.is_lt(a, b)`.

If either argument is [*NaN*](Num#is_nan), returns `Bool.false` no matter what. (*NaN*
is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
```roc
5
    |> Num.is_lt 6
```

is_gt : Num a, Num a -> Bool

Description:
Returns `Bool.true` if the first number is greater than the second.

`a > b` is shorthand for `Num.is_gt a b`.

If either argument is [*NaN*](Num#is_nan), returns `Bool.false` no matter what. (*NaN*
is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
```roc
Num.is_gt(6, 5)
```

is_lte : Num a, Num a -> Bool

Description:
Returns `Bool.true` if the first number is less than or equal to the second.

`a <= b` is shorthand for `Num.is_lte(a, b)`.

If either argument is [*NaN*](Num#is_nan), returns `Bool.false` no matter what. (*NaN*
is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)

is_gte : Num a, Num a -> Bool

Description:
Returns `Bool.true` if the first number is greater than or equal to the second.

`a >= b` is shorthand for `Num.is_gte(a, b)`.

If either argument is [*NaN*](Num#is_nan), returns `Bool.false` no matter what. (*NaN*
is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)

is_approx_eq : Frac a, Frac a, { rtol ? Frac a, atol ? Frac a } -> Bool

Description:
Returns `Bool.true` if the first number and second number are within a specific threshold

A specific relative and absolute tolerance can be provided to change the threshold

This function is symmetric: `Num.is_approx_eq(a, b) == Num.is_approx_eq(b, a)`

If either argument is [*NaN*](Num#is_nan), returns `Bool.false` no matter what. (*NaN*
is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)

is_zero : Num a -> Bool

Description:
Returns `Bool.true` if the number is `0`, and `Bool.false` otherwise.

is_even : Int a -> Bool

Description:
A number is even if dividing it by 2 gives a remainder of 0.

Examples of even numbers: 0, 2, 4, 6, 8, -2, -4, -6, -8

is_odd : Int a -> Bool

Description:
A number is odd if dividing it by 2 gives a remainder of 1.

Examples of odd numbers: 1, 3, 5, 7, -1, -3, -5, -7

is_positive : Num a -> Bool

Description:
Positive numbers are greater than `0`.

is_negative : Num a -> Bool

Description:
Negative numbers are less than `0`.

to_frac : Num * -> Frac *

is_nan : Frac * -> Bool

Description:
Returns `Bool.true` if the [Frac] is not a number as defined by [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)

```roc
Num.is_nan(0 / 0)
```

is_infinite : Frac * -> Bool

Description:
Returns `Bool.true` if the [Frac] is positive or negative infinity as defined by [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)

```roc
Num.is_infinite(1 / 0)

Num.is_infinite(-1 / 0)
```

is_finite : Frac * -> Bool

Description:
Returns `Bool.true` if the [Frac] is not an infinity as defined by [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)

```roc
Num.is_finite(42)
```

abs : Num a -> Num a

Description:
Returns the absolute value of the number.

* For a positive number, returns the same number.
* For a negative number, returns the same number except positive.
* For zero, returns zero.
```roc
Num.abs(4)

Num.abs(-2.5)

Num.abs(0)

Num.abs(0.0)
```
This is safe to use with any [Frac], but it can cause overflow when used with certain [Int] values.

For example, calling #Num.abs on the lowest value of a signed integer (such as [Num.min_i64] or [Num.min_i32]) will cause overflow.
This is because, for any given size of signed integer (32-bit, 64-bit, etc.) its negated lowest value turns out to be 1 higher than
the highest value it can represent. (For this reason, calling [Num.neg] on the lowest signed value will also cause overflow.)

Calling this on an unsigned integer (like [U32] or [U64]) never does anything.

abs_diff : Num a, Num a -> Num a

Description:
Returns the absolute difference between two numbers.

```roc
Num.abs_diff(5, 3)

Num.abs_diff(-3, 5)

Num.abs_diff(3.0, 5.0)
```

If the answer to this operation can't fit in the return value (e.g. an
[I8] answer that's higher than 127 or lower than -128), the result is an
*overflow*. For [F64] and [F32], overflow results in an answer of either
∞ or -∞. For all other number types, overflow results in a panic.

neg : Num a -> Num a

Description:
Returns a negative number when given a positive one, and vice versa.
```roc
Num.neg(5)

Num.neg(-2.5)

Num.neg(0)

Num.neg(0.0)
```
!! Num.neg is not completely implemented for all types in all contexts, see github.com/roc-lang/roc/issues/6959
You can use `\some_num -> 0 - some_num` as a workaround.

This is safe to use with any [Frac], but it can cause overflow when used with certain [Int] values.

For example, calling #Num.neg on the lowest value of a signed integer (such as [Num.min_i64] or [Num.min_i32]) will cause overflow.
This is because, for any given size of signed integer (32-bit, 64-bit, etc.) its negated lowest value turns out to be 1 higher than
the highest value it can represent. (For this reason, calling #Num.abs on the lowest signed value will also cause overflow.)

Additionally, calling #Num.neg on any unsigned integer (such as any [U64] or [U32] value) other than zero will cause overflow.

(It will never crash when given a [Frac], however, because of how floating point numbers represent positive and negative numbers.)

add : Num a, Num a -> Num a

Description:
Adds two numbers of the same type.

(To add an [Int] and a [Frac], first convert one so that they both have the same type. There are functions in this module that can convert both [Int] to [Frac] and the other way around.)

`a + b` is shorthand for `Num.add(a, b)`.
```roc
5 + 7

Num.add(5, 7)
```
`Num.add` can be convenient in pipelines.
```roc
Frac.pi
    |> Num.add(1.0)
```
If the answer to this operation can't fit in the return value (e.g. an
[I8] answer that's higher than 127 or lower than -128), the result is an
*overflow*. For [F64] and [F32], overflow results in an answer of either
∞ or -∞. For all other number types, overflow results in a panic.

sub : Num a, Num a -> Num a

Description:
Subtracts two numbers of the same type.

(To subtract an [Int] and a [Frac], first convert one so that they both have the same type. There are functions in this module that can convert both [Int] to [Frac] and the other way around.)

`a - b` is shorthand for `Num.sub(a, b)`.
```roc
7 - 5

Num.sub(7, 5)
```
`Num.sub` can be convenient in pipelines.
```roc
Frac.pi
    |> Num.sub(2.0)
```
If the answer to this operation can't fit in the return value (e.g. an
[I8] answer that's higher than 127 or lower than -128), the result is an
*overflow*. For [F64] and [F32], overflow results in an answer of either
∞ or -∞. For all other number types, overflow results in a panic.

mul : Num a, Num a -> Num a

Description:
Multiplies two numbers of the same type.

(To multiply an [Int] and a [Frac], first convert one so that they both have the same type. There are functions in this module that can convert both [Int] to [Frac] and the other way around.)

`a * b` is shorthand for `Num.mul(a, b)`.
```roc
5 * 7

Num.mul(5, 7)
```

`Num.mul` can be convenient in pipelines.

```roc
Frac.pi
    |> Num.mul(2.0)
```
If the answer to this operation can't fit in the return value (e.g. an
[I8] answer that's higher than 127 or lower than -128), the result is an
*overflow*. For [F64] and [F32], overflow results in an answer of either
∞ or -∞. For all other number types, overflow results in a panic.

min : Num a, Num a -> Num a

Description:
Obtains the smaller between two numbers of the same type.

```roc
Num.min(100, 0)

Num.min(3.0, -3.0)
```

max : Num a, Num a -> Num a

Description:
Obtains the greater between two numbers of the same type.

```roc
Num.max(100, 0)

Num.max(3.0, -3.0)
```

sin : Frac a -> Frac a

cos : Frac a -> Frac a

tan : Frac a -> Frac a

asin : Frac a -> Frac a

acos : Frac a -> Frac a

atan : Frac a -> Frac a

sqrt : Frac a -> Frac a

Description:
Returns an approximation of the absolute value of a [Frac]'s square root.

The square root of a negative number is an irrational number, and [Frac] only
supports rational numbers. As such, you should make sure never to pass this
function a negative number! Calling [sqrt] on a negative [Dec] will cause a panic.

Calling [sqrt] on [F32] and [F64] values follows these rules:
* Passing a negative [F64] or [F32] returns [*NaN*](Num#is_nan).
* Passing [*NaN*](Num#is_nan) or -∞ also returns [*NaN*](Num#is_nan).
* Passing ∞ returns ∞.

> These rules come from the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
> floating point standard. Because almost all modern processors are built to
> this standard, deviating from these rules has a significant performance
> cost! Since the most common reason to choose [F64] or [F32] over [Dec] is
> access to hardware-accelerated performance, Roc follows these rules exactly.
```roc
Num.sqrt(4.0)

Num.sqrt(1.5)

Num.sqrt(0.0)

Num.sqrt(-4.0f64)
```

sqrt_checked : Frac a -> Result (Frac a) [SqrtOfNegative]

log : Frac a -> Frac a

Description:
Natural logarithm

log_checked : Frac a -> Result (Frac a) [LogNeedsPositive]

div : Frac a, Frac a -> Frac a

Description:
Divides one [Frac] by another.

`a / b` is shorthand for `Num.div(a, b)`.

[Division by zero is undefined in mathematics](https://en.wikipedia.org/wiki/Division_by_zero).
As such, you should make sure never to pass zero as the denominator to this function!
Calling [div] on a [Dec] denominator of zero will cause a panic.

Calling [div] on [F32] and [F64] values follows these rules:
* Dividing a positive [F64] or [F32] by zero returns ∞.
* Dividing a negative [F64] or [F32] by zero returns -∞.
* Dividing a zero [F64] or [F32] by zero returns [*NaN*](Num#is_nan).

> These rules come from the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
> floating point standard. Because almost all modern processors are built to
> this standard, deviating from these rules has a significant performance
> cost! Since the most common reason to choose [F64] or [F32] over [Dec] is
> access to hardware-accelerated performance, Roc follows these rules exactly.

To divide an [Int] and a [Frac], first convert the [Int] to a [Frac] using
one of the functions in this module like #to_dec.
```roc
5.0 / 7.0

Num.div(5, 7)
```
`Num.div` can be convenient in pipelines.
```roc
Num.pi
    |> Num.div (2.0)
```

div_checked : Frac a, Frac a -> Result (Frac a) [DivByZero]

div_ceil : Int a, Int a -> Int a

div_ceil_checked : Int a, Int a -> Result (Int a) [DivByZero]

div_trunc : Int a, Int a -> Int a

Description:
Divides two integers, truncating the result towards zero.

`a // b` is shorthand for `Num.div_trunc(a, b)`.

Division by zero is undefined in mathematics. As such, you should make
sure never to pass zero as the denominator to this function! If you do,
it will crash.
```roc
5 // 7

Num.div_trunc(5, 7)

8 // -3

Num.div_trunc(8, -3)
```

div_trunc_checked : Int a, Int a -> Result (Int a) [DivByZero]

rem : Int a, Int a -> Int a

Description:
Obtains the remainder (truncating modulo) from the division of two integers.

`a % b` is shorthand for `Num.rem(a, b)`.
```roc
5 % 7

Num.rem(5, 7)

-8 % -3

Num.rem(-8, -3)
```

rem_checked : Int a, Int a -> Result (Int a) [DivByZero]

is_multiple_of : Int a, Int a -> Bool

bitwise_and : Int a, Int a -> Int a

Description:
Does a "bitwise and". Each bit of the output is 1 if the corresponding bit
of x AND of y is 1, otherwise it's 0.

bitwise_xor : Int a, Int a -> Int a

Description:
Does a "bitwise exclusive or". Each bit of the output is the same as the
corresponding bit in x if that bit in y is 0, and it's the complement of
the bit in x if that bit in y is 1.

bitwise_or : Int a, Int a -> Int a

Description:
Does a "bitwise or". Each bit of the output is 0 if the corresponding bit
of x OR of y is 0, otherwise it's 1.

bitwise_not : Int a -> Int a

Description:
Returns the complement of x - the number you get by switching each 1 for a
0 and each 0 for a 1. This is the same as -x - 1.

shift_left_by : Int a, U8 -> Int a

Description:
Bitwise left shift of a number by another

The least significant bits always become 0. This means that shifting left is
like multiplying by factors of two for unsigned integers.
```roc
shift_left_by(0b0000_0011, 2) == 0b0000_1100

0b0000_0101 |> shift_left_by(2) == 0b0001_0100
```
In some languages `shift_left_by` is implemented as a binary operator `<<`.

shift_right_by : Int a, U8 -> Int a

Description:
Bitwise arithmetic shift of a number by another

The most significant bits are copied from the current.
```roc
shift_right_by(0b0000_1100, 2) == 0b0000_0011

0b0001_0100 |> shift_right_by(2) == 0b0000_0101

0b1001_0000 |> shift_right_by(2) == 0b1110_0100
```
In some languages `shift_right_by` is implemented as a binary operator `>>>`.

shift_right_zf_by : Int a, U8 -> Int a

Description:
Bitwise logical right shift of a number by another

The most significant bits always become 0. This means that shifting right is
like dividing by factors of two for unsigned integers.
```roc
shift_right_zf_by(0b0010_1000, 2) == 0b0000_1010

0b0010_1000 |> shift_right_zf_by(2) == 0b0000_1010

0b1001_0000 |> shift_right_zf_by(2) == 0b0010_0100
```
In some languages `shift_right_zf_by` is implemented as a binary operator `>>`.

round : Frac * -> Int *

Description:
Round off the given fraction to the nearest integer.

floor : Frac * -> Int *

ceiling : Frac * -> Int *

pow : Frac a, Frac a -> Frac a

Description:
Raises a [Frac] to the power of another [Frac].

For an [Int] alternative to this function, see [Num.pow_int]

pow_int : Int a, Int a -> Int a

Description:
Raises an integer to the power of another, by multiplying the integer by
itself the given number of times.

This process is known as [exponentiation by squaring](https://en.wikipedia.org/wiki/Exponentiation_by_squaring).

For a [Frac] alternative to this function, which supports negative exponents,
see #Num.pow.

## Warning

It is very easy for this function to produce an answer
so large it causes an overflow.

count_leading_zero_bits : Int a -> U8

Description:
Counts the number of most-significant (leading in a big-Endian sense) zeroes in an integer.

```roc
Num.count_leading_zero_bits(0b0001_1100u8)

3

Num.count_leading_zero_bits(0b0000_0000u8)

8
```

count_trailing_zero_bits : Int a -> U8

Description:
Counts the number of least-significant (trailing in a big-Endian sense) zeroes in an integer.

```roc
Num.count_trailing_zero_bits(0b0001_1100u8)

2

Num.count_trailing_zero_bits(0b0000_0000u8)

8
```

count_one_bits : Int a -> U8

Description:
Counts the number of set bits in an integer.

```roc
Num.count_one_bits(0b0001_1100u8)

3

Num.count_one_bits(0b0000_0000u8)

0
```

add_wrap : Int range, Int range -> Int range

add_saturated : Num a, Num a -> Num a

Description:
Adds two numbers, clamping on the maximum representable number rather than
overflowing.

This is the same as [Num.add] except for the saturating behavior if the
addition is to overflow.
For example, if `x : U8` is 200 and `y : U8` is 100, `add_saturated x y` will
yield 255, the maximum value of a `U8`.

add_checked : Num a, Num a -> Result (Num a) [Overflow]

Description:
Adds two numbers and checks for overflow.

This is the same as [Num.add] except if the operation overflows, instead of
panicking or returning ∞ or -∞, it will return `Err Overflow`.

sub_wrap : Int range, Int range -> Int range

sub_saturated : Num a, Num a -> Num a

Description:
Subtracts two numbers, clamping on the minimum representable number rather
than overflowing.

This is the same as [Num.sub] except for the saturating behavior if the
subtraction is to overflow.
For example, if `x : U8` is 10 and `y : U8` is 20, `sub_saturated x y` will
yield 0, the minimum value of a `U8`.

sub_checked : Num a, Num a -> Result (Num a) [Overflow]

Description:
Subtracts two numbers and checks for overflow.

This is the same as [Num.sub] except if the operation overflows, instead of
panicking or returning ∞ or -∞, it will return `Err Overflow`.

mul_wrap : Int range, Int range -> Int range

mul_saturated : Num a, Num a -> Num a

Description:
Multiplies two numbers, clamping on the maximum representable number rather than
overflowing.

This is the same as [Num.mul] except for the saturating behavior if the
addition is to overflow.

mul_checked : Num a, Num a -> Result (Num a) [Overflow]

Description:
Multiplies two numbers and checks for overflow.

This is the same as [Num.mul] except if the operation overflows, instead of
panicking or returning ∞ or -∞, it will return `Err Overflow`.


## Integer Type Bounds

| Type | min | max |
|------|-----|-----|
| I8 | -128 | 127 |
| I16 | -32_768 | 32_767 |
| I32 | -2_147_483_648 | 2_147_483_647 |
| I64 | -9_223_372_036_854_775_808 | 9_223_372_036_854_775_807 |
| I128 | -170_141_183_460_469_231_731_687_303_715_884_105_728 | 170_141_183_460_469_231_731_687_303_715_884_105_727 |
| U8 | 0 | 255 |
| U16 | 0 | 65_535 |
| U32 | 0 | 4_294_967_295 |
| U64 | 0 | 18_446_744_073_709_551_615 |
| U128 | 0 | 340_282_366_920_938_463_463_374_607_431_768_211_455 |

Functions: `min_i8`, `max_i8`, `min_u8`, `max_u8`, etc. for all integer types.
Also: `min_f32`, `max_f32`, `min_f64`, `max_f64` for float bounds.

**Note**: For signed types, `|Num.abs(min_iN)|` > `max_iN`, so `Num.abs(min_iN)` will overflow.

to_i8 : Int * -> I8

Description:
Converts an [Int] to an [I8]. If the given number can't be precisely represented in an [I8],
the returned number may be different from the given number.

to_i16 : Int * -> I16

to_i32 : Int * -> I32

to_i64 : Int * -> I64

to_i128 : Int * -> I128

to_u8 : Int * -> U8

to_u16 : Int * -> U16

to_u32 : Int * -> U32

to_u64 : Int * -> U64

to_u128 : Int * -> U128

to_f32 : Num * -> F32

Description:
Converts a [Num] to an [F32]. If the given number can't be precisely represented in an [F32],
the returned number may be different from the given number.

to_f64 : Num * -> F64

Description:
Converts a [Num] to an [F64]. If the given number can't be precisely represented in an [F64],
the returned number may be different from the given number.

to_i8_checked : Int * -> Result I8 [OutOfBounds]

Description:
Converts a [Int] to an [I8].
If the given integer can't be precisely represented in an [I8], returns
`Err OutOfBounds`.

to_i16_checked : Int * -> Result I16 [OutOfBounds]

to_i32_checked : Int * -> Result I32 [OutOfBounds]

to_i64_checked : Int * -> Result I64 [OutOfBounds]

to_i128_checked : Int * -> Result I128 [OutOfBounds]

to_u8_checked : Int * -> Result U8 [OutOfBounds]

to_u16_checked : Int * -> Result U16 [OutOfBounds]

to_u32_checked : Int * -> Result U32 [OutOfBounds]

to_u64_checked : Int * -> Result U64 [OutOfBounds]

to_u128_checked : Int * -> Result U128 [OutOfBounds]

to_f32_checked : Num * -> Result F32 [OutOfBounds]

to_f64_checked : Num * -> Result F64 [OutOfBounds]

without_decimal_point : Dec -> I128

Description:
Turns a [Dec] into its [I128] representation by removing the decimal point.
This is equivalent to multiplying the [Dec] by 10^18.

with_decimal_point : I128 -> Dec

Description:
Turns a [I128] into the coresponding [Dec] by adding the decimal point.
This is equivalent to dividing the [I128] by 10^18.

f32_to_parts : F32 -> { sign : Bool, exponent : U8, fraction : U32 }

Description:
Splits a [F32] into its components according to IEEE 754 standard.

This function is deprecated due to common pitfalls when working with float components
using Roc’s fixed-size integer types. Please use [Num.f32_to_bits] instead and extract the
[IEEE 754 parts](https://en.wikipedia.org/wiki/Single-precision_floating-point_format#IEEE_754_standard:_binary32)
manually from the resulting [U32].

f64_to_parts : F64 -> { sign : Bool, exponent : U16, fraction : U64 }

Description:
Splits a [F64] into its components according to IEEE 754 standard.

This function is deprecated due to common pitfalls when working with float components
using Roc’s fixed-size integer types. Please use [Num.f64_to_bits] instead and extract the
[IEEE 754 parts](https://en.wikipedia.org/wiki/Double-precision_floating-point_format#IEEE_754_double-precision_binary_floating-point_format:_binary64)
manually from the resulting [U64].

f32_from_parts : { sign : Bool, exponent : U8, fraction : U32 } -> F32

Description:
Combine parts of a [F32] according to IEEE 754 standard.
The fraction should not be bigger than 0x007F_FFFF, any bigger value will be truncated.

This function is deprecated due to common pitfalls when working with float components
using Roc’s fixed-size integer types. Please combine the
[IEEE 754 parts](https://en.wikipedia.org/wiki/Single-precision_floating-point_format#IEEE_754_standard:_binary32)
manually into a [U32] and use [Num.f32_from_bits] to create the [F32] instead.

f64_from_parts : { sign : Bool, exponent : U16, fraction : U64 } -> F64

Description:
Combine parts of a [F64] according to IEEE 754 standard.
The fraction should not be bigger than 0x000F_FFFF_FFFF_FFFF, any bigger value will be truncated.
The exponent should not be bigger than 0x07FF, any bigger value will be truncated.

This function is deprecated due to common pitfalls when working with float components
using Roc’s fixed-size integer types. Please combine the
[IEEE 754 parts](https://en.wikipedia.org/wiki/Double-precision_floating-point_format#IEEE_754_double-precision_binary_floating-point_format:_binary64)
manually into a [U64] and use [Num.f64_from_bits] to create the [F64] instead.

f32_to_bits : F32 -> U32

Description:
Returns a [U32] containing the raw bits of a [F32], as defined by the IEEE 754 standard.

f64_to_bits : F64 -> U64

Description:
Returns a [U64] containing the raw bits of a [F64], as defined by the IEEE 754 standard.

dec_to_bits : Dec -> U128

Description:
Returns a [U128] containing the raw bits of a [Dec], which corresponds to the raw bits
of its [I128] representation.

f32_from_bits : U32 -> F32

Description:
Interprets a [U32] as the binary representation of a 32-bit floating-point value according
to the IEEE 754 standard and returns the corresponding [F32].

f64_from_bits : U64 -> F64

Description:
Interprets a [U64] as the binary representation of a 64-bit floating-point value according
to the IEEE 754 standard and returns the corresponding [F64].

dec_from_bits : U128 -> Dec

Description:
Interprets a [U128] as the raw bits of the internal [I128] representation of a fixed-point
decimal value and returns the corresponding [Dec].

from_bool : Bool -> Num *

Description:
Convert a `Bool` to a `Num`
```roc
expect Num.from_bool(Bool.true) == 1
expect Num.from_bool(Bool.false) == 0
```

nan_f32 : F32

Description:
The value for not-a-number for a [F32] according to the IEEE 754 standard.

nan_f64 : F64

Description:
The value for not-a-number for a [F64] according to the IEEE 754 standard.

infinity_f32 : F32

Description:
The value for infinity for a [F32] according to the IEEE 754 standard.

infinity_f64 : F64

Description:
The value for infinity for a [F64] according to the IEEE 754 standard.

### Bool

Eq : implements
    is_eq : a, a -> Bool
        where a implements Eq

Description:
Defines a type that can be compared for total equality.

Total equality means that all values of the type can be compared to each
other, and two values `a`, `b` are identical if and only if `is_eq(a, b)` is
`Bool.true`.

Not all types support total equality. For example, [`F32`](Num#F32) and [`F64`](Num#F64) can
be a `NaN` ([Not a Number](https://en.wikipedia.org/wiki/NaN)), and the
[IEEE-754](https://en.wikipedia.org/wiki/IEEE_754) floating point standard
specifies that two `NaN`s are not equal.

Description:
Represents the boolean true and false using an opaque type.
`Bool` implements the `Eq` ability.

true : Bool

Description:
The boolean true value.

false : Bool

Description:
The boolean false value.

not : Bool -> Bool

Description:
Returns `Bool.false` when given `Bool.true`, and vice versa. This is
equivalent to the logic [NOT](https://en.wikipedia.org/wiki/Negation)
gate. The operator `!` can also be used as shorthand for `Bool.not`.
```roc
expect Bool.not(Bool.false) == Bool.true
expect !Bool.false == Bool.true
```

is_not_eq : a, a -> Bool where a implements Eq

Description:
This will call the function `Bool.is_eq` on the inputs, and then `Bool.not`
on the result. The is equivalent to the logic
[XOR](https://en.wikipedia.org/wiki/Exclusive_or) gate. The infix operator
`!=` can also be used as shorthand for `Bool.is_not_eq`.

**Note** that `is_not_eq` does not accept arguments whose types contain
functions.
```roc
expect Bool.is_not_eq(Bool.false, Bool.true) == Bool.true
expect (Bool.false != Bool.false) == Bool.false
expect "Apples" != "Oranges"
```

### Result

Result : [ Ok ok, Err err ]

Description:
The result of an operation that could fail: either the operation went
okay, or else there was an error of some sort.

is_ok : Result ok err -> Bool

Description:
Returns `Bool.true` if the result indicates a success, else returns `Bool.false`.
```roc
Result.is_ok(Ok(5))
```

is_err : Result ok err -> Bool

Description:
Returns `Bool.true` if the result indicates a failure, else returns `Bool.false`.
```roc
Result.is_err(Err("uh oh"))
```

with_default : Result ok err, ok -> ok

Description:
If the result is `Ok`, returns the value it holds. Otherwise, returns
the given default value.

Note: This function should be used sparingly, because it hides that an error
happened, which will make debugging harder. Prefer using `?` to forward errors or
handle them explicitly with `when`.
```roc
Result.with_default(Err("uh oh"), 42) # = 42

Result.with_default(Ok(7), 42) # = 7
```

map_ok : Result a err, (a -> b) -> Result b err

Description:
If the result is `Ok`, transforms the value it holds by running a conversion
function on it. Then returns a new `Ok` holding the transformed value. If the
result is `Err`, this has no effect. Use [map_err] to transform an `Err`.
```roc
Result.map_ok(Ok(12), Num.neg) # = Ok(-12)

Result.map_ok(Err("yipes!"), Num.neg) # = Err("yipes!")
```
Functions like `map` are common in Roc; see for example [List.map],
`Set.map`, and `Dict.map`.

map_err : Result ok a, (a -> b) -> Result ok b

Description:
If the result is `Err`, transforms the value it holds by running a conversion
function on it. Then returns a new `Err` holding the transformed value. If
the result is `Ok`, this has no effect. Use [map_ok] to transform an `Ok`.
```roc
List.last([]) |> Result.map_err(|_| ProvidedListIsEmpty) # = Err(ProvidedListIsEmpty)

List.last([4]) |> Result.map_err(|_| ProvidedListIsEmpty) # = Ok(4)
```

on_err : Result a err, (err -> Result a other_err) -> Result a other_err

Description:
If the result is `Err`, transforms the entire result by running a conversion
function on the value the `Err` holds. Then returns that new result. If the
result is `Ok`, this has no effect. Use `?` or [try] to transform an `Ok`.
```roc
Result.on_err(Ok(10), Str.to_u64) # = Ok(10)

Result.on_err(Err("42"), Str.to_u64) # = Ok(42)

Result.on_err(Err("string"), Str.to_u64) # = Err(InvalidNumStr)
```

on_err! : Result a err, (err => Result a other_err) => Result a other_err

Description:
Like [on_err], but it allows the transformation function to produce effects.

```roc
Result.on_err(
    Err("missing user"),
    |msg|
        Stdout.line!("ERROR: ${msg}")?
        Err(msg)
)
```

map_both : Result ok1 err1, (ok1 -> ok2), (err1 -> err2) -> Result ok2 err2

Description:
Maps both the `Ok` and `Err` values of a `Result` to new values.

map2 : Result a err, Result b err, (a, b -> c) -> Result c err

Description:
Maps the `Ok` values of two `Result`s to a new value using a given transformation,
or returns the first `Err` value encountered.

try : Result a err, (a -> Result b err) -> Result b err

Description:
If the result is `Ok`, transforms the entire result by running a conversion
function on the value the `Ok` holds. Then returns that new result. If the
result is `Err`, this has no effect.

We recommend using `?` instead of `try`, it makes the code easier to read.
```roc
Result.try(Ok(-1), (|num| if num < 0 then Err("negative!") else Ok(-num))) # = Err("negative!")

Result.try(Err("yipes!"), (|num| -> if num < 0 then Err("negative!") else Ok(-num))) # = Err("yipes!")
```

### List

is_empty : List * -> Bool

Description:
 Check if the list is empty.
```roc
List.is_empty([1, 2, 3])

List.is_empty([])
```

get : List a, U64 -> Result a [OutOfBounds]

Description:
Returns an element from a list at the given index.

Returns `Err OutOfBounds` if the given index exceeds the List's length
```roc
expect List.get([100, 200, 300], 1) == Ok(200)
expect List.get([100, 200, 300], 5) == Err(OutOfBounds)
```

replace : List a, U64, a -> { list : List a, value : a }

set : List a, U64, a -> List a

Description:
Replaces the element at the given index with a replacement.
```roc
List.set(["a", "b", "c"], 1, "B")
```
If the given index is outside the bounds of the list, returns the original
list unmodified.

To drop the element at a given index, instead of replacing it, see [List.drop_at].

update : List a, U64, (a -> a) -> List a

Description:
Updates the element at the given index with the given function.
```roc
List.update([1, 2, 3], 1, (|x| x + 1))
```
If the given index is outside the bounds of the list, returns the original
list unmodified.

To replace the element at a given index, instead of updating based on the current value,
see [List.set] and [List.replace]

append : List a, a -> List a

Description:
Add a single element to the end of a list.
```roc
List.append([1, 2, 3], 4)

[0, 1, 2]
    |> List.append(3)
```

append_if_ok : List a, Result a * -> List a

Description:
If the given [Result] is `Ok`, add it to the end of a list.
Otherwise, return the list unmodified.

```roc
List.append_if_ok([1, 2, 3], Ok(4))

[0, 1, 2]
    |> List.append_if_ok(Err(3))
```

prepend : List a, a -> List a

Description:
Add a single element to the beginning of a list.
```roc
List.prepend([1, 2, 3], 0)

[2, 3, 4]
    |> List.prepend(1)
```

prepend_if_ok : List a, Result a * -> List a

Description:
If the given [Result] is `Ok`, add it to the beginning of a list.
Otherwise, return the list unmodified.

```roc
List.prepend([1, 2, 3], Ok(0))

[2, 3, 4]
    |> List.prepend(Err(1))
```

len : List * -> U64

Description:
Returns the length of the list - the number of elements it contains.

One [List] can store up to `Num.max_i64` elements on 64-bit targets and `Num.max_i32` on 32-bit targets like wasm.
This means the #U64 this function returns can always be safely converted to #I64 or #I32, depending on the target.

with_capacity : U64 -> List *

Description:
Create a list with space for at least capacity elements

reserve : List a, U64 -> List a

Description:
Enlarge the list for at least capacity additional elements

release_excess_capacity : List a -> List a

Description:
Shrink the memory footprint of a list such that it's capacity and length are equal.
Note: This will also convert seamless slices to regular lists.

concat : List a, List a -> List a

Description:
Put two lists together.
```roc
List.concat([1, 2, 3], [4, 5])

[0, 1, 2]
    |> List.concat([3, 4])
```

last : List a -> Result a [ListWasEmpty]

Description:
Returns the last element in the list, or `ListWasEmpty` if it was empty.
```roc
expect List.last([1, 2, 3]) == Ok(3)
expect List.last([]) == Err(ListWasEmpty)
```

single : a -> List a

Description:
A list with a single element in it.

This is useful in pipelines, like so:
```roc
websites =
    Str.concat(domain, ".com")
        |> List.single
```

repeat : a, U64 -> List a

Description:
Returns a list with the given length, where every element is the given value.

reverse : List a -> List a

Description:
Returns the list with its elements reversed.
```roc
expect List.reverse([1, 2, 3]) == [3, 2, 1]
```

join : List (List a) -> List a

Description:
Join the given lists together into one list.
```roc
expect List.join([[1], [2, 3], [], [4, 5]]) == [1, 2, 3, 4, 5]
expect List.join([[], []]) == []
expect List.join([]) == []
```

contains : List a, a -> Bool where a implements Eq

walk : List elem, state, (state, elem -> state) -> state

Description:
Build a value by folding over list elements from first to last. Also known as `reduce`, `fold`, `foldl`.
```roc
[2, 4, 8] |> List.walk(0, Num.add)  # returns 14
```

walk_with_index : List elem, state, (state, elem, U64 -> state) -> state

Description:
Like [walk], but at each step the function also receives the index of the current element.

walk_with_index_until : List elem, state, (state, elem, U64 -> [ Continue state, Break state ]) -> state

Description:
Like [walk_until], but at each step the function also receives the index of the current element.

walk_backwards : List elem, state, (state, elem -> state) -> state

Description:
Note that in other languages, `walk_backwards` is sometimes called `reduce_right`,
`fold`, `fold_right`, or `foldr`.

walk_until : List elem, state, (state, elem -> [ Continue state, Break state ]) -> state

Description:
Like [List.walk], but can stop early by returning `Break state`.

walk_backwards_until : List elem, state, (state, elem -> [ Continue state, Break state ]) -> state

Description:
Same as [List.walk_until], but does it from the end of the list instead.

walk_from : List elem, U64, state, (state, elem -> state) -> state

Description:
Walks to the end of the list from a specified starting index

walk_from_until : List elem, U64, state, (state, elem -> [ Continue state, Break state ]) -> state

Description:
A combination of [List.walk_from] and [List.walk_until]

sum : List (Num a) -> Num a

product : List (Num a) -> Num a

any : List a, (a -> Bool) -> Bool

Description:
Run the given predicate on each element of the list, returning `Bool.true` if
any of the elements satisfy it.

all : List a, (a -> Bool) -> Bool

Description:
Run the given predicate on each element of the list, returning `Bool.true` if
all of the elements satisfy it.

keep_if : List a, (a -> Bool) -> List a

Description:
Returns elements where the predicate returns `Bool.true`. Mutates in place if list is unique.
```roc
List.keep_if([1, 2, 3, 4], (|num| num > 2))  # [3, 4]
```


keep_if_try! : List a, (a => Result Bool err) => Result (List a) err

Description:
Run an effectful function that returns a [Result] on each element of a list, and return all the
elements for which the function returned `Ok(Bool.true)`.
```roc
dirs_only = List.keep_if_try!(path_list, Path.is_dir!)?
```


drop_if : List a, (a -> Bool) -> List a

Description:
Run the given function on each element of a list, and return all the
elements for which the function returned `Bool.false`.
```roc
List.drop_if([1, 2, 3, 4], (|num| num > 2))
```
## Performance Details

`List.drop_if` has the same performance characteristics as [List.keep_if].
See its documentation for details on those characteristics!

count_if : List a, (a -> Bool) -> U64

Description:
Run the given function on each element of a list, and return the
number of elements for which the function returned `Bool.true`.
```roc
expect List.count_if([1, -2, -3], Num.is_negative) == 2
expect List.count_if([1, 2, 3], (|num| num > 1)) == 2
```

keep_oks : List before, (before -> Result after *) -> List after

Description:
This works like [List.map], except only the transformed values that are
wrapped in `Ok` are kept. Any that are wrapped in `Err` are dropped.
```roc
expect List.keep_oks(["1", "Two", "23", "Bird"], Str.to_i32) == [1, 23]

expect List.keep_oks([["a", "b"], [], ["c", "d", "e"], [] ], List.first) == ["a", "c"]

fn = |str| if Str.is_empty(str) then Err(StrWasEmpty) else Ok(str)
expect List.keep_oks(["", "a", "bc", "", "d", "ef", ""], fn) == ["a", "bc", "d", "ef"]
```

keep_errs : List before, (before -> Result * after) -> List after

Description:
This works like [List.map], except only the transformed values that are
wrapped in `Err` are kept. Any that are wrapped in `Ok` are dropped.
```roc
List.keep_errs([["a", "b"], [], [], ["c", "d", "e"]], List.last)

fn = |str| if Str.is_empty(str) then Err(StrWasEmpty) else Okd(Str.len(str))

List.keep_errs(["", "a", "bc", "", "d", "ef", ""], fn)
```

map : List a, (a -> b) -> List b

Description:
Convert each element in the list to something new, by calling a conversion
function on each of them. Then return a new list of the converted values.
```roc
expect List.map([1, 2, 3], (|num| num + 1)) == [2, 3, 4]

expect List.map(["", "a", "bc"], Str.is_empty) == [Bool.true, Bool.false, Bool.false]
```

map2 : List a, List b, (a, b -> c) -> List c

Description:
Run a transformation function on the first element of each list,
and use that as the first element in the returned list.
Repeat until a list runs out of elements.

Some languages have a function named `zip`, which does something similar to
calling [List.map2] passing two lists and `Pair`:
```roc
zipped = List.map2(["a", "b", "c"], [1, 2, 3], Pair)
```

map3 : List a, List b, List c, (a, b, c -> d) -> List d

Description:
Run a transformation function on the first element of each list,
and use that as the first element in the returned list.
Repeat until a list runs out of elements.

map4 : List a, List b, List c, List d, (a, b, c, d -> e) -> List e

Description:
Run a transformation function on the first element of each list,
and use that as the first element in the returned list.
Repeat until a list runs out of elements.

map_with_index : List a, (a, U64 -> b) -> List b

Description:
This works like [List.map], except it also passes the index
of the element to the conversion function.
```roc
expect List.map_with_index([10, 20, 30], (|num, index| num + index)) == [10, 21, 32]
```

Description:
Returns a list of all the integers between `start` and `end`.

To include the `start` and `end` integers themselves, use `At` like so:
```roc
List.range({ start: At 2, end: At 5 }) == [2, 3, 4, 5]
```
To exclude them, use `After` and `Before`, like so:
```roc
List.range({ start: After 2, end: Before 5 }) == [3, 4]
```
You can have the list end at a certain length rather than a certain integer:
```roc
List.range({ start: At 6, end: Length 4 }) == [6, 7, 8, 9]
```
If `step` is specified, each integer increases by that much. (`step: 1` is the default.)
```roc
List.range({ start: After 0, end: Before 9, step: 3 }) == [3, 6]
```
List.range will also generate a reversed list if step is negative or end comes before start:
```roc
List.range({ start: At 5, end: At 2 }) == [5, 4, 3, 2]
```
All of these options are compatible with the others. For example, you can use `At` or `After`
with `start` regardless of what `end` and `step` are set to.

sort_with : List a, (a, a -> [ LT, EQ, GT ]) -> List a

Description:
Sort with a custom comparison function

sort_asc : List (Num a) -> List (Num a)

Description:
Sorts a list of numbers in ascending order (lowest to highest).

To sort in descending order (highest to lowest), use [List.sort_desc] instead.

sort_desc : List (Num a) -> List (Num a)

Description:
Sorts a list of numbers in descending order (highest to lowest).

To sort in ascending order (lowest to highest), use [List.sort_asc] instead.

swap : List a, U64, U64 -> List a

first : List a -> Result a [ListWasEmpty]

Description:
Returns the first element in the list, or `ListWasEmpty` if it was empty.

take_first : List elem, U64 -> List elem

Description:
Returns the given number of elements from the beginning of the list.
```roc
List.take_first([1, 2, 3, 4, 5, 6, 7, 8], 4) == [1, 2, 3, 4]
```
If there are fewer elements in the list than the requested number,
returns the entire list.
```roc
List.take_first([1, 2], 5) == [1, 2]
```
To *remove* elements from the beginning of the list, use `List.take_last`.

To remove elements from both the beginning and end of the list,
use `List.sublist`.

To split the list into two lists, use `List.split_at`.


take_last : List elem, U64 -> List elem

Description:
Returns the given number of elements from the end of the list.
```roc
List.take_last([1, 2, 3, 4, 5, 6, 7, 8], 4) == [5, 6, 7, 8]
```
If there are fewer elements in the list than the requested number,
returns the entire list.
```roc
List.take_last([1, 2], 5) == [1, 2]
```
To *remove* elements from the end of the list, use `List.take_first`.

To remove elements from both the beginning and end of the list,
use `List.sublist`.

To split the list into two lists, use `List.split_at`.


drop_first : List elem, U64 -> List elem

Description:
Drops n elements from the beginning of the list.

drop_last : List elem, U64 -> List elem

Description:
Drops n elements from the end of the list.

drop_at : List elem, U64 -> List elem

Description:
Drops the element at the given index from the list.

This has no effect if the given index is outside the bounds of the list.

To replace the element at a given index, instead of dropping it, see [List.set].

min : List (Num a) -> Result (Num a) [ListWasEmpty]

max : List (Num a) -> Result (Num a) [ListWasEmpty]

join_map : List a, (a -> List b) -> List b

Description:
Like [List.map], except the transformation function wraps the return value
in a list. At the end, all the lists get joined together into one list.

You may know a similar function named `concat_map` in other languages.

find_first : List elem, (elem -> Bool) -> Result elem [NotFound]

Description:
Returns the first element of the list satisfying a predicate function.
If no satisfying element is found, an `Err NotFound` is returned.

find_last : List elem, (elem -> Bool) -> Result elem [NotFound]

Description:
Returns the last element of the list satisfying a predicate function.
If no satisfying element is found, an `Err NotFound` is returned.

find_first_index : List elem, (elem -> Bool) -> Result U64 [NotFound]

Description:
Returns the index at which the first element in the list
satisfying a predicate function can be found.
If no satisfying element is found, an `Err NotFound` is returned.

find_last_index : List elem, (elem -> Bool) -> Result U64 [NotFound]

Description:
Returns the last index at which the first element in the list
satisfying a predicate function can be found.
If no satisfying element is found, an `Err NotFound` is returned.

sublist : List elem, { start : U64, len : U64 } -> List elem

Description:
Returns a subsection of the given list, beginning at the `start` index and
including a total of `len` elements.

If `start` is outside the bounds of the given list, returns the empty list.
```roc
List.sublist([1, 2, 3], { start: 4, len: 0 })
```
If more elements are requested than exist in the list, returns as many as it can.
```roc
List.sublist([1, 2, 3, 4, 5], { start: 2, len: 10 })
```
> If you want a sublist which goes all the way to the end of the list, no
> matter how long the list is, `List.take_last` can do that more efficiently.

Some languages have a function called **`slice`** which works similarly to this.

intersperse : List elem, elem -> List elem

Description:
Intersperses `sep` between the elements of `list`
```roc
List.intersperse([1, 2, 3], 9) == [1, 9, 2, 9, 3]
```

starts_with : List elem, List elem -> Bool where elem implements Eq

Description:
Returns `Bool.true` if the first list starts with the second list.

If the second list is empty, this always returns `Bool.true`; every list
is considered to "start with" an empty list.

If the first list is empty, this only returns `Bool.true` if the second list is empty.

ends_with : List elem, List elem -> Bool where elem implements Eq

Description:
Returns `Bool.true` if the first list ends with the second list.

If the second list is empty, this always returns `Bool.true`; every list
is considered to "end with" an empty list.

If the first list is empty, this only returns `Bool.true` if the second list is empty.

split_at : List elem, U64 -> { before : List elem, others : List elem }

Description:
Splits the list into two lists, around the given index.

The returned lists are labeled `before` and `others`. The `before` list will
contain all the elements whose index in the original list was **less than**
than the given index, # and the `others` list will be all the others. (This
means if you give an index of 0, the `before` list will be empty and the
`others` list will have the same elements as the original list.)

split_on : List a, a -> List (List a) where a implements Eq

Description:
Splits the input list on the delimiter element.

```roc
List.split_on([1, 2, 3], 2) == [[1], [3]]
```

split_on_list : List a, List a -> List (List a) where a implements Eq

Description:
Splits the input list on the delimiter list.

```roc
List.split_on_list([1, 2, 3], [1, 2]) == [[], [3]]
```

split_first : List elem, elem -> Result { before : List elem, after : List elem } [NotFound] where elem implements Eq

Description:
Returns the elements before the first occurrence of a delimiter, as well as the
remaining elements after that occurrence. If the delimiter is not found, returns `Err`.
```roc
List.split_first([Foo, Z, Bar, Z, Baz], Z) == Ok({ before: [Foo], after: [Bar, Z, Baz] })
```

split_last : List elem, elem -> Result { before : List elem, after : List elem } [NotFound] where elem implements Eq

Description:
Returns the elements before the last occurrence of a delimiter, as well as the
remaining elements after that occurrence. If the delimiter is not found, returns `Err`.
```roc
List.split_last([Foo, Z, Bar, Z, Baz], Z) == Ok({ before: [Foo, Z, Bar], after: [Baz] })
```

chunks_of : List a, U64 -> List (List a)

Description:
Splits the list into many chunks, each of which is length of the given chunk
size. The last chunk will be shorter if the list does not evenly divide by the
chunk size. If the provided list is empty or if the chunk size is 0 then the
result is an empty list.

map_try : List elem, (elem -> Result ok err) -> Result (List ok) err

Description:
Like [List.map], except the transformation function returns a [Result].
If that function ever returns `Err`, [map_try] immediately returns that `Err`.
If it returns `Ok` for every element, [map_try] returns `Ok` with the transformed list.

map_try! : List elem, (elem => Result ok err) => Result (List ok) err

Description:
Like [List.map_try], but with an effectful function.
```
file_list = ["a.txt", "b.txt", "c.txt"]
file_contents =
    List.map_try!(file_list, |file| File.read_utf8!(file))
```

walk_try : List elem, state, (state, elem -> Result state err) -> Result state err

Description:
Like [List.walk], but stops early and returns `Err` if the function returns `Err`.

concat_utf8 : List U8, Str -> List U8

Description:
Concatenates the bytes of a string encoded as utf8 to a list of bytes.
```roc
expect List.concat_utf8([1, 2, 3, 4], "🐦") == [1, 2, 3, 4, 240, 159, 144, 166]
```

for_each! : List a, (a => {}) => {}

Description:
Run an effectful function for each element on the list.

```roc
List.for_each!(["Alice", "Bob", "Charlie"], |name|
    create_account!(name)
    log!("Account created")
)
```

If the function might fail or you need to return early, use [for_each_try!].

for_each_try! : List a, (a => Result {} err) => Result {} err

Description:
Run an effectful function that might fail for each element on the list.

If the function returns `Err`, the iteration stops and the error is returned.

```roc
List.for_each_try!(files_to_delete, |path|
    File.delete!(path)?

    Stdout.line!("${path} deleted")
)
```

walk! : List elem, state, (state, elem => state) => state

Description:
Build a value from the contents of a list, using an effectful function.

```roc
now_multiples = List.walk!([1, 2, 3], [], |nums, i|
     now = Utc.now!({}) |> Utc.to_millis_since_epoch
     List.append(nums, now * i)
)
```

This is the same as [walk], except that the step function can have effects.

walk_try! : List elem, state, (state, elem => Result state err) => Result state err

Description:
Build a value from the contents of a list, using an effectful function that might fail.

If the function returns `Err`, the iteration stops and the error is returned.

```
names =
    List.walk_try!(
        ["First", "Middle", "Last"],
        [],
        |accumulator, which|
            Stdout.write!("${which} name: ")?
            name = Stdin.line!({})?
            Ok(List.append(accumulator, name)),
    )?
```

This is the same as [walk_try], except that the step function can have effects.

### Dict

Associative array mapping keys to values. Maintains insertion order for [Dict.keys]/[Dict.values], but [Dict.remove] moves last element into removed slot (O(1) removal). Based on IndexMap/unordered_dense.
```roc
Dict.empty({}) |> Dict.insert("London", 8_961_989) |> Dict.get("London")  # Ok(8_961_989)
```

empty : {} -> Dict * *

Description:
Return an empty dictionary.
```roc
empty_dict = Dict.empty({})
```

with_capacity : U64 -> Dict * *

Description:
Return a dictionary with space allocated for a number of entries. This
may provide a performance optimization if you know how many entries will be
inserted.

reserve : Dict k v, U64 -> Dict k v

Description:
Enlarge the dictionary for at least capacity additional elements

release_excess_capacity : Dict k v -> Dict k v

Description:
Shrink the memory footprint of a dictionary such that capacity is as small as possible.
This function will require regenerating the metadata if the size changes.
There will still be some overhead due to dictionary metadata always being a power of 2.

capacity : Dict * * -> U64

Description:
Returns the max number of elements the dictionary can hold before requiring a rehash.
```roc
food_dict =
    Dict.empty({})
    |> Dict.insert("apple", "fruit")

capacity_of_dict = Dict.capacity(food_dict)
```

single : k, v -> Dict k v

Description:
Returns a dictionary containing the key and value provided as input.
```roc
expect
    Dict.single("A", "B")
    |> Bool.is_eq(Dict.empty({}) |> Dict.insert("A", "B"))
```

from_list : List ( k, v ) -> Dict k v

Description:
Returns dictionary with the keys and values specified by the input [List].
```roc
expect
    Dict.single(1, "One")
    |> Dict.insert(2, "Two")
    |> Dict.insert(3, "Three")
    |> Dict.insert(4, "Four")
    |> Bool.is_eq(Dict.from_list([(1, "One"), (2, "Two"), (3, "Three"), (4, "Four")]))
```

## Performance Details

This will build up from an empty dictionary to minimize totally memory use.
If the list has few duplicate keys, it would be faster to allocate a dictionary
with the same capacity of the list and walk it calling [Dict.insert]

len : Dict * * -> U64

Description:
Returns the number of values in the dictionary.
```roc
expect
    Dict.empty({})
    |> Dict.insert("One", "A Song")
    |> Dict.insert("Two", "Candy Canes")
    |> Dict.insert("Three", "Boughs of Holly")
    |> Dict.len
    |> Bool.is_eq(3)
```

is_empty : Dict * * -> Bool

Description:
Check if the dictionary is empty.
```roc
Dict.is_empty(Dict.empty({}) |> Dict.insert("key", 42))

Dict.is_empty(Dict.empty({}))
```

clear : Dict k v -> Dict k v

Description:
Clears all elements from a dictionary keeping around the allocation if it isn't huge.
```roc
songs =
       Dict.empty({})
       |> Dict.insert("One", "A Song")
       |> Dict.insert("Two", "Candy Canes")
       |> Dict.insert("Three", "Boughs of Holly")

clear_songs = Dict.clear(songs)

expect Dict.len(clear_songs) == 0
```

map : Dict k a, (k, a -> b) -> Dict k b

Description:
Convert each value in the dictionary to something new, by calling a conversion
function on each of them which receives both the key and the old value. Then return a
new dictionary containing the same keys and the converted values.

join_map : Dict a b, (a, b -> Dict x y) -> Dict x y

Description:
Like [Dict.map], except the transformation function wraps the return value
in a dictionary. At the end, all the dictionaries get joined together
(using [Dict.insert_all]) into one dictionary.

You may know a similar function named `concat_map` in other languages.

walk : Dict k v, state, (state, k, v -> state) -> state

Description:
Iterate through the keys and values in the dictionary and call the provided
function with signature `state, k, v -> state` for each value, with an
initial `state` value provided for the first call.
```roc
expect
    Dict.empty({})
    |> Dict.insert("Apples", 12)
    |> Dict.insert("Orange", 24)
    |> Dict.walk(0, (\count, _, qty -> count + qty))
    |> Bool.is_eq(36)
```

walk_until : Dict k v, state, (state, k, v -> [ Continue state, Break state ]) -> state

Description:
Like [Dict.walk], but can stop early by returning `Break state`.

keep_if : Dict k v, ( ( k, v ) -> Bool) -> Dict k v

Description:
Run the given function on each key-value pair of a dictionary, and return
a dictionary with just the pairs for which the function returned `Bool.true`.
```roc
expect Dict.empty({})
    |> Dict.insert("Alice", 17)
    |> Dict.insert("Bob", 18)
    |> Dict.insert("Charlie", 19)
    |> Dict.keep_if(\(_k, v) -> v >= 18)
    |> Dict.len
    |> Bool.is_eq(2)
```

drop_if : Dict k v, ( ( k, v ) -> Bool) -> Dict k v

Description:
Run the given function on each key-value pair of a dictionary, and return
a dictionary with just the pairs for which the function returned `Bool.false`.
```roc
expect Dict.empty({})
    |> Dict.insert("Alice", 17)
    |> Dict.insert("Bob", 18)
    |> Dict.insert("Charlie", 19)
    |> Dict.drop_if(\(_k, v) -> v >= 18)
    |> Dict.len
    |> Bool.is_eq(1)
```

get : Dict k v, k -> Result v [KeyNotFound]

Description:
Get the value for a given key. If there is a value for the specified key it
will return [Ok value], otherwise return [Err KeyNotFound].
```roc
dictionary =
    Dict.empty({})
    |> Dict.insert(1,s "Apple")
    |> Dict.insert(2,s "Orange")

expect Dict.get(dictionary, 1) == Ok("Apple")
expect Dict.get(dictionary, 2000) == Err(KeyNotFound)
```

contains : Dict k v, k -> Bool

Description:
Check if the dictionary has a value for a specified key.
```roc
expect
    Dict.empty({})
    |> Dict.insert(1234, "5678")
    |> Dict.contains(1234)
    |> Bool.is_eq(Bool.true)
```

insert : Dict k v, k, v -> Dict k v

Description:
Insert a value into the dictionary at a specified key.
```roc
expect
    Dict.empty({})
    |> Dict.insert("Apples", 12)
    |> Dict.get("Apples")
    |> Bool.is_eq(Ok(12))
```

remove : Dict k v, k -> Dict k v

Description:
Remove a value from the dictionary for a specified key.
```roc
expect
    Dict.empty({})
    |> Dict.insert("Some", "Value")
    |> Dict.remove("Some")
    |> Dict.len
    |> Bool.is_eq(0)
```

update : Dict k v, k, (Result v [Missing] -> Result v [Missing]) -> Dict k v

Description:
Insert or remove a value for a specified key. This function enables a
performance optimization for the use case of providing a default when a value
is missing. This is more efficient than doing both a `Dict.get` and then a
`Dict.insert` call, and supports being piped.
```roc
alter_value : Result Bool [Missing] -> Result Bool [Missing]
alter_value = \possible_value ->
    when possible_value is
        Err Missing -> Ok(Bool.false)
        Ok value -> if value then Err(Missing) else Ok(Bool.true)

expect Dict.update(Dict.empty({}), "a", alter_value) == Dict.single("a", Bool.false)
expect Dict.update(Dict.single("a", Bool.false), "a", alter_value) == Dict.single("a", Bool.true)
expect Dict.update(Dict.single("a", Bool.true), "a", alter_value) == Dict.empty({})
```

to_list : Dict k v -> List ( k, v )

Description:
Returns the keys and values of a dictionary as a [List].
This requires allocating a temporary list, prefer using [Dict.to_list] or [Dict.walk] instead.
```roc
expect
    Dict.single(1, "One")
    |> Dict.insert(2, "Two")
    |> Dict.insert(3, "Three")
    |> Dict.insert(4, "Four")
    |> Dict.to_list
    |> Bool.is_eq([(1, "One"), (2, "Two"), (3, "Three"), (4, "Four")])
```

keys : Dict k v -> List k

Description:
Returns the keys of a dictionary as a [List].
This requires allocating a temporary [List], prefer using [Dict.to_list] or [Dict.walk] instead.
```roc
expect
    Dict.single(1, "One")
    |> Dict.insert(2, "Two")
    |> Dict.insert(3, "Three")
    |> Dict.insert(4, "Four")
    |> Dict.keys
    |> Bool.is_eq([1,2,3,4])
```

values : Dict k v -> List v

Description:
Returns the values of a dictionary as a [List].
This requires allocating a temporary [List], prefer using [Dict.to_list] or [Dict.walk] instead.
```roc
expect
    Dict.single(1, "One")
    |> Dict.insert(2, "Two")
    |> Dict.insert(3, "Three")
    |> Dict.insert(4, "Four")
    |> Dict.values
    |> Bool.is_eq(["One","Two","Three","Four"])
```

insert_all : Dict k v, Dict k v -> Dict k v

Description:
Combine two dictionaries by keeping the [union](https://en.wikipedia.org/wiki/Union_(set_theory))
of all the key-value pairs. This means that all the key-value pairs in
both dictionaries will be combined. Note that where there are pairs
with the same key, the value contained in the second input will be
retained, and the value in the first input will be removed.
```roc
first =
    Dict.single(1, "Not Me")
    |> Dict.insert(2, "And Me")

second =
    Dict.single(1, "Keep Me")
    |> Dict.insert(3, "Me Too")
    |> Dict.insert(4, "And Also Me")

expected =
    Dict.single(1, "Keep Me")
    |> Dict.insert(2, "And Me")
    |> Dict.insert(3, "Me Too")
    |> Dict.insert(4, "And Also Me")

expect
    Dict.insert_all(first, second) == expected
```

keep_shared : Dict k v, Dict k v -> Dict k v where v implements Eq

Description:
Combine two dictionaries by keeping the [intersection](https://en.wikipedia.org/wiki/Intersection_(set_theory))
of all the key-value pairs. This means that we keep only those pairs
that are in both dictionaries. Both the key and value must match to be kept.
```roc
first =
    Dict.single(1, "Keep Me")
    |> Dict.insert(2, "And Me")
    |> Dict.insert(3, "Not this one")

second =
    Dict.single(1, "Keep Me")
    |> Dict.insert(2, "And Me")
    |> Dict.insert(3, "This has a different value")
    |> Dict.insert(4, "Or Me")

expected =
    Dict.single(1, "Keep Me")
    |> Dict.insert(2, "And Me")

expect Dict.keep_shared(first, second) == expected
```

remove_all : Dict k v, Dict k v -> Dict k v

Description:
Remove the key-value pairs in the first input that are also in the second
using the [set difference](https://en.wikipedia.org/wiki/Complement_(set_theory)#Relative_complement)
of the values. This means that we will be left with only those pairs that
are in the first dictionary and whose keys are not in the second.
```roc
first =
    Dict.single(1, "Keep Me")
    |> Dict.insert(2, "And Me")
    |> Dict.insert(3, "Remove Me")

second =
    Dict.single(3, "Remove Me")
    |> Dict.insert(4, "I do nothing...")

expected =
    Dict.single(1, "Keep Me")
    |> Dict.insert(2, "And Me")

expect Dict.remove_all(first, second) == expected
```

### Set

Description:
Provides a [set](https://en.wikipedia.org/wiki/Set_(abstract_data_type))
type which stores a collection of unique values, without any ordering

empty : {} -> Set *

Description:
Creates a new empty `Set`.
```roc
empty_set = Set.empty({})
count_values = Set.len(empty_set)

expect count_values == 0
```

with_capacity : U64 -> Set *

Description:
Return a set with space allocated for a number of entries. This
may provide a performance optimization if you know how many entries will be
inserted.

reserve : Set k, U64 -> Set k

Description:
Enlarge the set for at least capacity additional elements

release_excess_capacity : Set k -> Set k

Description:
Shrink the memory footprint of a set such that capacity is as small as possible.
This function will require regenerating the metadata if the size changes.
There will still be some overhead due to dictionary metadata always being a power of 2.

single : k -> Set k

Description:
Creates a new `Set` with a single value.
```roc
single_item_set = Set.single("Apple")
count_values = Set.len(single_item_set)

expect count_values == 1
```

insert : Set k, k -> Set k

Description:
Insert a value into a `Set`.
```roc
few_item_set =
    Set.empty({})
    |> Set.insert("Apple")
    |> Set.insert("Pear")
    |> Set.insert("Banana")

count_values = Set.len(few_item_set)

expect count_values == 3
```

len : Set * -> U64

Description:
Counts the number of values in a given `Set`.
```roc
few_item_set =
    Set.empty({})
    |> Set.insert("Apple")
    |> Set.insert("Pear")
    |> Set.insert("Banana")

count_values = Set.len(few_item_set)

expect count_values == 3
```

capacity : Set * -> U64

Description:
Returns the max number of elements the set can hold before requiring a rehash.
```roc
food_set =
    Set.empty({})
    |> Set.insert("apple")

capacity_of_set = Set.capacity(food_set)
```

is_empty : Set * -> Bool

Description:
Check if the set is empty.
```roc
Set.is_empty(Set.empty({}) |> Set.insert(42))

Set.is_empty(Set.empty({}))
```

remove : Set k, k -> Set k

Description:
Removes the value from the given `Set`.
```roc
numbers =
    Set.empty({})
    |> Set.insert(10)
    |> Set.insert(20)
    |> Set.remove(10)

has10 = Set.contains(numbers, 10)
has20 = Set.contains(numbers, 20)

expect has10 == Bool.false
expect has20 == Bool.true
```

contains : Set k, k -> Bool

Description:
Test if a value is in the `Set`.
```roc
Fruit : [Apple, Pear, Banana]

fruit : Set Fruit
fruit =
    Set.single(Apple)
    |> Set.insert(Pear)

has_apple = Set.contains(fruit, Apple)
has_banana = Set.contains(fruit, Banana)

expect has_apple == Bool.true
expect has_banana == Bool.false
```

to_list : Set k -> List k

Description:
Retrieve the values in a `Set` as a `List`.
```roc
numbers : Set U64
numbers = Set.from_list([1,2,3,4,5])

values = [1,2,3,4,5]

expect Set.to_list(numbers) == values
```

from_list : List k -> Set k

Description:
Create a `Set` from a `List` of values.
```roc
values =
    Set.empty({})
    |> Set.insert(Banana)
    |> Set.insert(Apple)
    |> Set.insert(Pear)

expect Set.from_list([Pear, Apple, Banana]) == values
```

union : Set k, Set k -> Set k

Description:
Combine two `Set` collection by keeping the
[union](https://en.wikipedia.org/wiki/Union_(set_theory))
of all the values pairs. This means that all of the values in both `Set`s
will be combined.
```roc
set1 = Set.single(Left)
set2 = Set.single(Right)

expect Set.union(set1, set2) == Set.from_list([Left, Right])
```

intersection : Set k, Set k -> Set k

Description:
Combine two `Set`s by keeping the [intersection](https://en.wikipedia.org/wiki/Intersection_(set_theory))
of all the values pairs. This means that we keep only those values that are
in both `Set`s.
```roc
set1 = Set.from_list([Left, Other])
set2 = Set.from_list([Left, Right])

expect Set.intersection(set1, set2) == Set.single(Left)
```

difference : Set k, Set k -> Set k

Description:
Remove the values in the first `Set` that are also in the second `Set`
using the [set difference](https://en.wikipedia.org/wiki/Complement_(set_theory)#Relative_complement)
of the values. This means that we will be left with only those values that
are in the first and not in the second.
```roc
first = Set.from_list([Left, Right, Up, Down])
second = Set.from_list([Left, Right])

expect Set.difference(first, second) == Set.from_list([Up, Down])
```

walk : Set k, state, (state, k -> state) -> state

Description:
Iterate through the values of a given `Set` and build a value.
```roc
values = Set.from_list(["March", "April", "May"])

starts_with_letter_m = \month ->
    when Str.to_utf8(month) is
        ['M', ..] -> Bool.true
        _ -> Bool.false

reduce = \state, k ->
    if starts_with_letter_m(k) then
        state + 1
    else
        state

result = Set.walk(values, 0, reduce)

expect result == 2
```

map : Set a, (a -> b) -> Set b

Description:
Convert each value in the set to something new, by calling a conversion
function on each of them which receives the old value. Then return a
new set containing the converted values.

join_map : Set a, (a -> Set b) -> Set b

Description:
Like [Set.map], except the transformation function wraps the return value
in a set. At the end, all the sets get joined together
(using [Set.union]) into one set.

You may know a similar function named `concat_map` in other languages.

walk_until : Set k, state, (state, k -> [ Continue state, Break state ]) -> state

Description:
Iterate through the values of a given `Set` and build a value, can stop
iterating part way through the collection.
```roc
numbers = Set.from_list([1,2,3,4,5,6,42,7,8,9,10])

find42 = \state, k ->
    if k == 42 then
        Break(FoundTheAnswer)
    else
        Continue(state)

result = Set.walk_until(numbers, NotFound, find42)

expect result == FoundTheAnswer
```

keep_if : Set k, (k -> Bool) -> Set k

Description:
Run the given function on each element in the `Set`, and return
a `Set` with just the elements for which the function returned `Bool.true`.
```roc
expect Set.from_list([1,2,3,4,5])
    |> Set.keep_if(\k -> k >= 3)
    |> Bool.is_eq(Set.from_list([3,4,5]))
```

drop_if : Set k, (k -> Bool) -> Set k

Description:
Run the given function on each element in the `Set`, and return
a `Set` with just the elements for which the function returned `Bool.false`.
```roc
expect Set.from_list [1,2,3,4,5]
    |> Set.drop_if(\k -> k >= 3)
    |> Bool.is_eq(Set.from_list([1,2]))
```

### Decode

DecodeError : [TooShort]

Description:
Error types when decoding a `List U8` of utf-8 bytes using a [Decoder]

Description:
Return type of a [Decoder].

This can be useful when creating a [custom](#custom) decoder or when
using [from_bytes_partial](#from_bytes_partial). For example writing unit tests,
such as;
```roc
expect
    input = "\"hello\", " |> Str.to_utf8
    actual = Decode.from_bytes_partial(input, Json.json)
    expected = Ok("hello")

    actual.result == expected
```

Description:
Decodes a `List U8` of utf-8 bytes where `val` is the type of the decoded
value, and `fmt` is a [Decoder] which implements the [DecoderFormatting]
ability

Decoding : implements
    decoder : Decoder val fmt
        where val implements Decoding, fmt implements DecoderFormatting

Description:
Definition of the [Decoding] ability

DecoderFormatting : implements
    u8 : Decoder U8 fmt
        where fmt implements DecoderFormatting
    u16 : Decoder U16 fmt
        where fmt implements DecoderFormatting
    u32 : Decoder U32 fmt
        where fmt implements DecoderFormatting
    u64 : Decoder U64 fmt
        where fmt implements DecoderFormatting
    u128 : Decoder U128 fmt
        where fmt implements DecoderFormatting
    i8 : Decoder I8 fmt
        where fmt implements DecoderFormatting
    i16 : Decoder I16 fmt
        where fmt implements DecoderFormatting
    i32 : Decoder I32 fmt
        where fmt implements DecoderFormatting
    i64 : Decoder I64 fmt
        where fmt implements DecoderFormatting
    i128 : Decoder I128 fmt
        where fmt implements DecoderFormatting
    f32 : Decoder F32 fmt
        where fmt implements DecoderFormatting
    f64 : Decoder F64 fmt
        where fmt implements DecoderFormatting
    dec : Decoder Dec fmt
        where fmt implements DecoderFormatting
    bool : Decoder Bool fmt
        where fmt implements DecoderFormatting
    string : Decoder Str fmt
        where fmt implements DecoderFormatting
    list : Decoder elem fmt -> Decoder (List elem) fmt
        where fmt implements DecoderFormatting
    record : 
        state,         
        (state, 
        Str
        -> 
            [
                Keep (Decoder state fmt),
                Skip
            ]), 
        (state, fmt -> Result val DecodeError)
        -> Decoder val fmt
        where fmt implements DecoderFormatting
    tuple : 
        state,         
        (state, 
        U64
        -> 
            [
                Next (Decoder state fmt),
                TooLong
            ]), 
        (state -> Result val DecodeError)
        -> Decoder val fmt
        where fmt implements DecoderFormatting

Description:
Definition of the [DecoderFormatting] ability

custom : (List U8, fmt -> DecodeResult val) -> Decoder val fmt where fmt implements DecoderFormatting

Description:
Build a custom [Decoder] function. For example the implementation of
`decode_bool` could be defined as follows;

```roc
decode_bool = Decode.custom \bytes, @Json({}) ->
    when bytes is
        ['f', 'a', 'l', 's', 'e', ..] -> { result: Ok(Bool.false), rest: List.drop_first(bytes, 5) }
        ['t', 'r', 'u', 'e', ..] -> { result: Ok Bool.true, rest: List.drop_first(bytes, 4) }
        _ -> { result: Err(TooShort), rest: bytes }
```

decode_with : List U8, Decoder val fmt, fmt -> DecodeResult val where fmt implements DecoderFormatting

Description:
Decode a `List U8` utf-8 bytes using a specific [Decoder] function

from_bytes_partial : List U8, fmt -> DecodeResult val where val implements Decoding, fmt implements DecoderFormatting

Description:
Decode a `List U8` utf-8 bytes and return a [DecodeResult](#DecodeResult)
```roc
expect
    input = "\"hello\", " |> Str.to_utf8
    actual = Decode.from_bytes_partial(input Json.json)
    expected = Ok("hello")

    actual.result == expected
```

from_bytes : List U8, fmt -> Result val [Leftover (List U8)]DecodeError where val implements Decoding, fmt implements DecoderFormatting

Description:
Decode a `List U8` utf-8 bytes and return a [Result] with no leftover bytes
expected. If successful returns `Ok val`, however, if there are bytes
remaining returns `Err Leftover (List U8)`.
```roc
expect
    input = "\"hello\", " |> Str.to_utf8
    actual = Decode.from_bytes(input, Json.json)
    expected = Ok("hello")

    actual == expected
```

map_result : DecodeResult a, (a -> b) -> DecodeResult b

Description:
Transform the `val` of a [DecodeResult]

### Encode

Encoding : implements
    to_encoder : val -> Encoder fmt
        where val implements Encoding, fmt implements EncoderFormatting

EncoderFormatting : implements
    u8 : U8 -> Encoder fmt
        where fmt implements EncoderFormatting
    u16 : U16 -> Encoder fmt
        where fmt implements EncoderFormatting
    u32 : U32 -> Encoder fmt
        where fmt implements EncoderFormatting
    u64 : U64 -> Encoder fmt
        where fmt implements EncoderFormatting
    u128 : U128 -> Encoder fmt
        where fmt implements EncoderFormatting
    i8 : I8 -> Encoder fmt
        where fmt implements EncoderFormatting
    i16 : I16 -> Encoder fmt
        where fmt implements EncoderFormatting
    i32 : I32 -> Encoder fmt
        where fmt implements EncoderFormatting
    i64 : I64 -> Encoder fmt
        where fmt implements EncoderFormatting
    i128 : I128 -> Encoder fmt
        where fmt implements EncoderFormatting
    f32 : F32 -> Encoder fmt
        where fmt implements EncoderFormatting
    f64 : F64 -> Encoder fmt
        where fmt implements EncoderFormatting
    dec : Dec -> Encoder fmt
        where fmt implements EncoderFormatting
    bool : Bool -> Encoder fmt
        where fmt implements EncoderFormatting
    string : Str -> Encoder fmt
        where fmt implements EncoderFormatting
    list : List elem, (elem -> Encoder fmt) -> Encoder fmt
        where fmt implements EncoderFormatting
    record :         List 
        {
            key : Str,
            value : Encoder fmt
        }
        -> Encoder fmt
        where fmt implements EncoderFormatting
    tuple : List (Encoder fmt) -> Encoder fmt
        where fmt implements EncoderFormatting
    tag : Str, List (Encoder fmt) -> Encoder fmt
        where fmt implements EncoderFormatting

custom : (List U8, fmt -> List U8) -> Encoder fmt where fmt implements EncoderFormatting

Description:
Creates a custom encoder from a given function.

```roc
expect
    # Appends the byte 42
    custom_encoder = Encode.custom(\bytes, _fmt -> List.append(bytes, 42))

    actual = Encode.append_with([], custom_encoder, Core.json)
    expected = [42] # Expected result is a list with a single byte, 42

    actual == expected
```

append_with : List U8, Encoder fmt, fmt -> List U8 where fmt implements EncoderFormatting

append : List U8, val, fmt -> List U8 where val implements Encoding, fmt implements EncoderFormatting

Description:
Appends the encoded representation of a value to an existing list of bytes.

```roc
expect
    actual = Encode.append([], { foo: 43 }, Core.json)
    expected = Str.to_utf8("""{"foo":43}""")

    actual == expected
```

to_bytes : val, fmt -> List U8 where val implements Encoding, fmt implements EncoderFormatting

Description:
Encodes a value to a list of bytes (`List U8`) according to the specified format.

```roc
expect
    foo_rec = { foo: 42 }

    actual = Encode.to_bytes(foo_rec, Core.json)
    expected = Str.to_utf8("""{"foo":42}""")

    actual == expected
```

### Hash

Hash : implements
    hash : hasher, a -> hasher
        where a implements Hash, hasher implements Hasher

Description:
A value that can be hashed.

Hasher : implements
    add_bytes : a, List U8 -> a
        where a implements Hasher
    add_u8 : a, U8 -> a
        where a implements Hasher
    add_u16 : a, U16 -> a
        where a implements Hasher
    add_u32 : a, U32 -> a
        where a implements Hasher
    add_u64 : a, U64 -> a
        where a implements Hasher
    add_u128 : a, U128 -> a
        where a implements Hasher
    complete : a -> U64
        where a implements Hasher

Description:
Describes a hashing algorithm that is fed bytes and produces an integer hash.

The [Hasher] ability describes general-purpose hashers. It only allows
emission of 64-bit unsigned integer hashes. It is not suitable for
cryptographically-secure hashing.

Description:
Adds a string into a [Hasher] by hashing its UTF-8 bytes.

Description:
Adds a list of [Hash]able elements to a [Hasher] by hashing each element.

hash_bool : a, Bool -> a where a implements Hasher

Description:
Adds a single [Bool] to a hasher.

hash_i8 : a, I8 -> a where a implements Hasher

Description:
Adds a single I8 to a hasher.

hash_i16 : a, I16 -> a where a implements Hasher

Description:
Adds a single I16 to a hasher.

hash_i32 : a, I32 -> a where a implements Hasher

Description:
Adds a single I32 to a hasher.

hash_i64 : a, I64 -> a where a implements Hasher

Description:
Adds a single I64 to a hasher.

hash_i128 : a, I128 -> a where a implements Hasher

Description:
Adds a single I128 to a hasher.

hash_dec : a, Dec -> a where a implements Hasher

Description:
Adds a single [Dec] to a hasher.

Description:
Adds a container of [Hash]able elements to a [Hasher] by hashing each element.
The container is iterated using the walk method passed in.
The order of the elements does not affect the final hash.

### Box

box : a -> Box a

Description:
Allocates a value on the heap. Boxing is an expensive process as it copies
the value from the stack to the heap. This may provide a performance
optimization for advanced use cases with large values. A platform may require
that some values are boxed.
```roc
expect Box.unbox(Box.box("Stack Faster")) == "Stack Faster"
```

unbox : Box a -> a

Description:
Returns a boxed value.
```roc
expect Box.unbox(Box.box("Stack Faster") == "Stack Faster"
```

### Inspect

KeyValWalker : collection, state, (state, key, val -> state) -> state

ElemWalker : collection, state, (state, elem -> state) -> state

InspectFormatter : implements
    init : {} -> f
        where f implements InspectFormatter
    tag : Str, List (Inspector f) -> Inspector f
        where f implements InspectFormatter
    tuple : List (Inspector f) -> Inspector f
        where f implements InspectFormatter
    record :         List 
        {
            key : Str,
            value : Inspector f
        }
        -> Inspector f
        where f implements InspectFormatter
    bool : Bool -> Inspector f
        where f implements InspectFormatter
    str : Str -> Inspector f
        where f implements InspectFormatter
    list : 
        list, 
        ElemWalker state list elem, 
        (elem -> Inspector f)
        -> Inspector f
        where f implements InspectFormatter
    set : 
        set, 
        ElemWalker state set elem, 
        (elem -> Inspector f)
        -> Inspector f
        where f implements InspectFormatter
    dict : 
        dict, 
        KeyValWalker state dict key value, 
        (key -> Inspector f), 
        (value -> Inspector f)
        -> Inspector f
        where f implements InspectFormatter
    opaque : * -> Inspector f
        where f implements InspectFormatter
    function : * -> Inspector f
        where f implements InspectFormatter
    u8 : U8 -> Inspector f
        where f implements InspectFormatter
    i8 : I8 -> Inspector f
        where f implements InspectFormatter
    u16 : U16 -> Inspector f
        where f implements InspectFormatter
    i16 : I16 -> Inspector f
        where f implements InspectFormatter
    u32 : U32 -> Inspector f
        where f implements InspectFormatter
    i32 : I32 -> Inspector f
        where f implements InspectFormatter
    u64 : U64 -> Inspector f
        where f implements InspectFormatter
    i64 : I64 -> Inspector f
        where f implements InspectFormatter
    u128 : U128 -> Inspector f
        where f implements InspectFormatter
    i128 : I128 -> Inspector f
        where f implements InspectFormatter
    f32 : F32 -> Inspector f
        where f implements InspectFormatter
    f64 : F64 -> Inspector f
        where f implements InspectFormatter
    dec : Dec -> Inspector f
        where f implements InspectFormatter

custom : (f -> f) -> Inspector f where f implements InspectFormatter

apply : Inspector f, f -> f where f implements InspectFormatter

Inspect : implements
    to_inspector : val -> Inspector f
        where val implements Inspect, f implements InspectFormatter

inspect : val -> f where val implements Inspect, f implements InspectFormatter

to_str : val -> Str where val implements Inspect

