@@ -1,3405 +0,0 @@
-## 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
-
@@ -1,707 +0,0 @@
-# Roc Language Reference
-
-## REPL
-
-Run with `roc repl`. Online: [roc-lang.org/repl](https://www.roc-lang.org/repl)
-
-```roc
-greeting = "Hi"
-audience = "World"
-```
-
-Arithmetic: `1 + 2 * (3 - 4)` follows order of operations.
-
-## Calling Functions
-
-```roc
-Str.concat("Hi ", "there.") # "Hi there."
-```
-
-`Str` is a module, `concat` is a function in that module.
-
-### String Interpolation
-
-```roc
-"${greeting} there, ${audience}."
-"Two plus three is: ${Num.to_str(2 + 3)}"
-```
-
-## Building an Application
-
-```roc
-app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.20.0/X73hGh05nNTkDHU06FHC0YfFaQB1pimX7gncRcao5mU.tar.br" }
-
-import pf.Stdout
-
-main! = |_args|
- Stdout.line!("Hi there, from inside a Roc app. ๐")
-```
-
-Run: `roc main.roc`
-
-### Defs
-
-```roc
-birds = 3
-iguanas = 2
-total = Num.to_str(birds + iguanas)
-
-main! = |_args|
- Stdout.line!("There are ${total} animals.")
-```
-
-Defs are constantโcannot be reassigned.
-
-### Defining Functions
-
-```roc
-add_and_stringify = |num1, num2|
- Num.to_str(num1 + num2)
-```
-
-### if-then-else
-
-```roc
-add_and_stringify = |num1, num2|
- sum = num1 + num2
- if sum == 0 then
- ""
- else if sum < 0 then
- "negative"
- else
- Num.to_str(sum)
-```
-
-Every `if` must have both `then` and `else`.
-
-### Comments
-
-```roc
-# Single line comment
-## Doc comment (included in generated docs)
-## x = 2 # Code block in doc (5 spaces after ##)
-```
-
-### Records
-
-```roc
-add_and_stringify = |counts|
- Num.to_str(counts.birds + counts.iguanas)
-
-total = add_and_stringify({ birds: 5, iguanas: 7 })
-```
-
-Functions accept records with extra fields:
-
-```roc
-total_with_note = add_and_stringify({ birds: 4, iguanas: 3, note: "Whee!" })
-```
-
-### Record Shorthands
-
-```roc
-return_foo = .foo # Same as |record| record.foo
-{ x: x, y: y } # Same as { x, y }
-```
-
-### Record Destructuring
-
-```roc
-add_and_stringify = |{ birds, iguanas }|
- Num.to_str(birds + iguanas)
-
-add_and_stringify = |{ birds, iguanas: lizards }| # Rename field
- Num.to_str(birds + lizards)
-
-{ x, y } = { x: 5, y: 10 } # Destructure in defs
-```
-
-### Record Update
-
-```roc
-original = { birds: 5, zebras: 2, iguanas: 7, goats: 1 }
-from_original = { original & birds: 4, iguanas: 3 }
-```
-
-`&` cannot introduce new fields or change types.
-
-### Debugging with dbg
-
-```roc
-pluralize = |singular, plural, count|
- dbg count # Prints: [pluralize.roc 6:8] 5
- if count == 1 then singular else plural
-
-dbg Str.concat(singular, plural) # Any expression
-inc = |n| 1 + dbg n # As function in expression
-```
-
-### Tuples
-
-```roc
-tuple = ("hello", 42, ["list"])
-first = tuple.0 # "hello"
-second = tuple.1 # 42
-
-(first, second, third) = ("hello", 42, ["list"]) # Destructuring
-```
-
-## Pattern Matching
-
-### Tags
-
-```roc
-stoplight_color =
- if something > 0 then Red
- else if something == 0 then Yellow
- else Green
-```
-
-Tags are capitalized literals (like numbers/strings, no definition needed).
-
-### when/is
-
-```roc
-stoplight_str =
- when stoplight_color is
- Red -> "red"
- Green -> "green"
- Yellow -> "yellow"
-```
-
-Catch-all with `_`:
-
-```roc
-when stoplight_color is
- Red -> "red"
- _ -> "not red"
-```
-
-Multiple tags with `|`:
-
-```roc
-when stoplight_color is
- Red -> "red"
- Green | Yellow -> "not red"
-```
-
-Guards with `if`:
-
-```roc
-when stoplight_color is
- Red -> "red"
- Green | Yellow if contrast > 75 -> "high contrast"
- Green | Yellow -> "not red"
-```
-
-### Tags with Payloads
-
-```roc
-stoplight_color =
- if something > 100 then Red
- else if something > 0 then Yellow
- else Custom("some other color")
-
-stoplight_str =
- when stoplight_color is
- Red -> "red"
- Green | Yellow -> "not red"
- Custom(description) -> description
-```
-
-Multi-value payloads: `Custom(40, 60, 80)` destructured as `Custom(r, g, b) ->`
-
-### Booleans
-
-`Bool.true` and `Bool.false` (not keywords). Prefer tags for data modeling:
-
-```roc
-{ name: "Richard", role: Admin } # Better than is_admin: Bool.true
-```
-
-## Lists
-
-```roc
-names = ["Sam", "Lee", "Ari"]
-List.append(names, "Jess") # Returns new list (immutable)
-```
-
-### List.map
-
-```roc
-List.map([1, 2, 3], |num| num * 2) # [2, 4, 6]
-List.map([1, 2, 3], Num.is_odd) # [Bool.true, Bool.false, Bool.true]
-```
-
-All list elements must share a type. Use tags for mixed types:
-
-```roc
-List.map([StrElem "A", NumElem 1], |elem|
- when elem is
- NumElem(num) -> Num.is_negative(num)
- StrElem(str) -> Str.starts_with(str, "A")
-)
-```
-
-### Using Tags as Functions
-
-```roc
-List.map(["a", "b", "c"], Foo) # Same as |str| Foo(str)
-```
-
-### List.any / List.all
-
-```roc
-List.any([1, 2, 3], Num.is_odd) # Bool.true
-List.all([1, 2, 3], Num.is_positive) # Bool.true
-```
-
-### Removing Elements
-
-```roc
-List.drop_at(["Sam", "Lee", "Ari"], 1) # ["Sam", "Ari"]
-List.keep_if([1, 2, 3, 4, 5], Num.is_even) # [2, 4]
-List.drop_if([1, 2, 3, 4, 5], Num.is_even) # [1, 3, 5]
-```
-
-### Getting Elements
-
-```roc
-List.get(["a", "b", "c"], 1) # Ok "b"
-List.get(["a", "b", "c"], 100) # Err(OutOfBounds)
-List.first(list) # Err(ListWasEmpty) if empty
-List.last(list) # Err(ListWasEmpty) if empty
-```
-
-## Error Handling
-
-```roc
-Result.with_default(List.get(["a", "b", "c"], 100), "") # ""
-Result.isOk(List.get(["a", "b", "c"], 1)) # Bool.true
-```
-
-### ? Postfix Operator
-
-Unwraps `Ok`, returns early on `Err`:
-
-```roc
-get_letter : Str -> Result Str [OutOfBounds, InvalidNumStr]
-get_letter = |index_str|
- index = Str.to_u64(index_str)?
- List.get(["a", "b", "c", "d"], index)
-```
-
-### ?? Infix Operator (Default on Error)
-
-```roc
-List.get(["a", "b", "c"], 100) ?? "" # ""
-```
-
-### List.walk
-
-```roc
-List.walk([1, 2, 3, 4, 5], { evens: [], odds: [] }, |state, elem|
- if Num.is_even(elem) then
- { state & evens: List.append(state.evens, elem) }
- else
- { state & odds: List.append(state.odds, elem) }
-)
-# { evens: [2, 4], odds: [1, 3, 5] }
-```
-
-Arguments: list, initial state, function `(state, elem) -> state`
-
-### Pattern Matching on Lists
-
-```roc
-when my_list is
- [] -> 0 # empty
- [Foo, ..] -> 1 # starts with Foo
- [_, ..] -> 2 # at least one element
- [Foo, Bar, Baz] -> 3 # exactly 3 elements
- [Foo, a, ..] -> 4 # second element named `a`
- [Ok a, ..] -> 5 # first is Ok with payload
- [.., Foo] -> 6 # ends with Foo
- [A, B, .., C, D] -> 7 # specific start and end
- [head, .. as tail] -> 8 # head and rest
-```
-
-Only one `..` (rest pattern) per pattern.
-
-### Pipe Operator
-
-```roc
-["a", "b", "c"] |> List.get(1) |> Result.with_default("")
-# Same as: Result.with_default(List.get(["a", "b", "c"], 1), "")
-```
-
-## Types
-
-### Type Annotations
-
-```roc
-full_name : Str, Str -> Str
-full_name = |first_name, last_name|
- "${first_name} ${last_name}"
-
-first_name : Str
-first_name = "Amy"
-
-amy : { first_name : Str, last_name : Str }
-amy = { first_name: "Amy", last_name: "Lee" }
-```
-
-### Type Aliases
-
-```roc
-Musician : { first_name : Str, last_name : Str }
-
-amy : Musician
-amy = { first_name: "Amy", last_name: "Lee" }
-```
-
-### Type Parameters
-
-```roc
-names : List Str
-names = ["Amy", "Simone", "Tarja"]
-```
-
-### Wildcard Type (*)
-
-```roc
-is_empty : List * -> Bool # Works on any list type
-```
-
-Empty list `[]` has type `List *`.
-
-### Type Variables
-
-```roc
-reverse : List elem -> List elem # Same element type in and out
-```
-
-Lowercase names (`elem`, `a`, `value`) are type variables.
-
-### Tag Union Types
-
-```roc
-color_from_str : Str -> [Red, Green, Yellow]
-color_from_str = |string|
- when string is
- "red" -> Red
- "green" -> Green
- _ -> Yellow
-```
-
-Tag unions accumulate:
-
-```roc
-|str|
- if Str.is_empty(str) then Ok "it was empty"
- else Err ["it was not empty"]
-# Type: Str -> [Ok Str, Err (List Str)]
-```
-
-`Result ok err` is alias for `[Ok ok, Err err]`.
-
-### Opaque Types
-
-```roc
-Username := Str
-
-from_str : Str -> Username
-from_str = |str| @Username(str)
-
-to_str : Username -> Str
-to_str = |@Username(str)| str
-```
-
-`@Username` only usable in defining module.
-
-### Integers
-
-| Type | Range |
-|------|-------|
-| U8 | 0 to 255 |
-| I8 | -128 to 127 |
-| U16 | 0 to 65,535 |
-| I16 | -32,768 to 32,767 |
-| U32 | 0 to 4,294,967,295 |
-| I32 | -2,147,483,648 to 2,147,483,647 |
-| U64 | 0 to 18+ quintillion |
-| I64 | -9+ to 9+ quintillion |
-| U128 | 0 to 340+ undecillion |
-| I128 | ยฑ170+ undecillion |
-
-Overflow crashes the program.
-
-### Fractions
-
-| Type | Description |
-|------|-------------|
-| F32 | 32-bit floating-point |
-| F64 | 64-bit floating-point |
-| Dec | 128-bit decimal fixed-point (18 decimal places) |
-
-`Dec` is best for currency/base-10. `F32`/`F64` have precision loss with decimals.
-
-### Num, Int, Frac
-
-```roc
-abs : Num a -> Num a # Any number
-bitwise_xor : Int a, Int a -> Int a # Integers only
-cos : Frac a -> Frac a # Fractions only
-```
-
-Number literals have type `Num *` (or `Frac *` with decimal point).
-
-### Number Literal Suffixes
-
-```roc
-1u8 # U8
-5dec # Dec
-0xfe # Hex (254)
-0b1000 # Binary (8)
-```
-
-Suffixes: `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `u64`, `i64`, `u128`, `i128`, `f32`, `f64`, `dec`
-
-### Default-Value Record Fields
-
-```roc
-table : { height : U64, width : U64, title ?? Str, description ?? Str } -> Table
-table = |{ height, width, title ?? "oak", description ?? "a wooden table" }| ...
-```
-
-`??` in types marks optional fields. Only accessible via destructuring.
-
-## Crashing
-
-Crashes: integer overflow, out of memory, `crash` keyword.
-
-```roc
-when Str.from_utf8(bytes) is
- Ok(str) -> str
- Err(_) -> crash "This should never happen!"
-
-# TODO marker
-crash "TODO handle the x <= y case"
-```
-
-Not for error handlingโuse `Result` instead.
-
-## Testing
-
-```roc
-pluralize = |singular, plural, count|
- if count == 1 then "${Num.to_str(count)} ${singular}"
- else "${Num.to_str(count)} ${plural}"
-
-expect pluralize("cactus", "cacti", 1) == "1 cactus"
-expect pluralize("cactus", "cacti", 2) == "2 cacti"
-```
-
-Run: `roc test`
-
-### Inline Expects
-
-```roc
-pluralize = |singular, plural, count|
- if count == 1 then "${Num.to_str(count)} ${singular}"
- else
- expect count > 0
- "${Num.to_str(count)} ${plural}"
-```
-
-- `roc build`: discards all expects
-- `roc dev`: runs inline expects during execution
-- `roc test`: runs top-level expects and triggered inline expects
-
-## Modules
-
-Types: `app` (application), `module`, `package`, `platform`, `hosted`
-
-### Builtin Modules (auto-imported)
-
-Str, Num, Bool, Result, List, Dict, Set, Decode, Encode, Hash, Box, Inspect
-
-### App Module Header
-
-```roc
-app [main!] { pf: platform "https://..." }
-
-import pf.Stdout
-import AdditionalModule
-import uuid.Generate as Uuid
-import pf.Stdout exposing [line!]
-```
-
-### Importing Files
-
-```roc
-import "some-file" as some_str : Str
-import "some-file" as some_bytes : List U8
-```
-
-## Effectful Functions
-
-Pure functions: `->`, effectful: `=>`
-
-```roc
-with_extension : Str -> Str # Pure
-read_file! : Str => Str # Effectful
-```
-
-Effectful functions can call pure or effectful. Pure can only call pure.
-`!` suffix is naming convention (compiler-enforced).
-
-```roc
-Stdout.line! : Str => Result {} [StdoutErr IOErr]
-Stdin.line! : {} => Result Str [EndOfFile, StdinErr IOErr]
-```
-
-### Reading Input
-
-```roc
-main! = |_args|
- Stdout.line!("Type something:")?
- input = Stdin.line!({})?
- Stdout.line!("You entered: ${input}")
-```
-
-### Handling Failure
-
-```roc
-main! : List Arg => Result {} [Exit I32 Str]
-main! = |_args|
- Result.map_err(my_function!({}), |err|
- when err is
- StdoutErr(_) -> Exit(1i32, "Error writing to stdout.")
- StdinErr(_) -> Exit(2i32, "Error writing to stdin.")
- EndOfFile -> Exit(3i32, "End of file reached.")
- )
-```
-
-### Tagging Errors
-
-```roc
-main! = |_args|
- Stdout.line!("Prompt") ? UnableToPrintPrompt
- input = Stdin.line!({}) ? UnableToReadInput
- Stdout.line!("You entered: ${input}") ? UnableToPrintInput
- Ok({})
-```
-
-### Inspect.to_str
-
-```roc
-Inspect.to_str(any_value) # String representation for debugging
-```
-
-### Early return
-
-```roc
-if this_is_a_bad_time then
- return "Error message"
-else
- continue_normally
-```
-
-## Advanced Concepts
-
-### Open vs Closed Records
-
-```roc
-# Closed: exact fields only
-full_name : { first_name : Str, last_name : Str } -> Str
-
-# Open: at least these fields (note the *)
-full_name : { first_name : Str, last_name : Str }* -> Str
-
-# Constrained: same type in and out
-add_https : { url : Str }a -> { url : Str }a
-```
-
-Inference:
-- Creating record โ closed
-- Using as argument/destructuring โ open
-- Record update โ constrained
-
-### Type Alias with Variable
-
-```roc
-User a : { email : Str, first_name : Str, last_name : Str }a
-
-is_valid : User * -> Bool # Open
-user_from_email : Str -> User {} # Closed
-capitalize : User a -> User a # Constrained
-```
-
-### Open vs Closed Tag Unions
-
-```roc
-# Open: might have unknown tags (needs _ -> branch)
-example : [Foo Str, Bar Bool]* -> Bool
-example = |tag|
- when tag is
- Foo(str) -> Str.is_empty(str)
- Bar(bool) -> bool
- _ -> Bool.false
-
-# Closed: exactly these tags
-example : [Foo Str, Bar Bool] -> Bool
-example = |tag|
- when tag is
- Foo(str) -> Str.is_empty(str)
- Bar(bool) -> bool
-```
-
-New tags are inferred as open unions and can accumulate through conditionals.
-
-### Constrained Tag Unions
-
-```roc
-example : [Foo Str, Bar Bool]a -> [Foo Str, Bar Bool]a
-example = |tag|
- when tag is
- Foo(str) -> Bar(Str.is_empty(str))
- Bar(bool) -> Bar(Bool.false)
- other -> other
-```
-
-### Record Builder
-
-```roc
-user_tab_matcher =
- { combine_matchers <-
- _: exact_segment("users"), # Ignored field
- user_id: u64_segment,
- tab: any_segment,
- }
-```
-
-Desugars to nested `combine_matchers` calls.
-
-### Reserved Keywords
-
-`as`, `crash`, `dbg`, `else`, `expect`, `expect-fx`, `if`, `import`, `is`, `return`, `then`, `try`, `when`
-
-### Operator Desugaring
-
-| Operator | Desugars To |
-|----------|-------------|
-| `a + b` | `Num.add(a, b)` |
-| `a - b` | `Num.sub(a, b)` |
-| `a * b` | `Num.mul(a, b)` |
-| `a / b` | `Num.div(a, b)` |
-| `a // b` | `Num.div_trunc(a, b)` |
-| `a ^ b` | `Num.pow(a, b)` |
-| `a % b` | `Num.rem(a, b)` |
-| `-a` | `Num.neg(a)` |
-| `a == b` | `Bool.is_eq(a, b)` |
-| `a != b` | `Bool.is_not_eq(a, b)` |
-| `a && b` | `Bool.and(a, b)` |
-| `a \|\| b` | `Bool.or(a, b)` |
-| `!a` | `Bool.not(a)` |
-| `a \|> f` | `f(a)` |