# LLM Prompt for Documentation

## Documentation

### Str

#### Utf8ByteProblem

**Type Annotation**

```roc

    [
        InvalidStartByte,
        UnexpectedEndOfSequence,
        ExpectedContinuation,
        OverlongEncoding,
        CodepointTooLarge,
        EncodesSurrogateHalf
    ]
```

#### Utf8Problem

**Type Annotation**

#### isEmpty

**Type Annotation**

```roc
Str -> Bool
```

**Description**

Returns [Bool.true] if the string is empty, and [Bool.false] otherwise.
```roc
expect Str.isEmpty "hi!" == Bool.false
expect Str.isEmpty "" == Bool.true
```

#### concat

**Type Annotation**

```roc
Str, Str -> Str
```

**Description**

Concatenates two strings together.
```roc
expect Str.concat "ab" "cd" == "abcd"
expect Str.concat "hello" "" == "hello"
expect Str.concat "" "" == ""
```

#### withCapacity

**Type Annotation**

```roc
U64 -> Str
```

**Description**

Returns a string of the specified capacity without any content.

This is a performance optimization tool that's like calling [Str.reserve] on an empty string.
It's useful when you plan to build up a string incrementally, for example by calling [Str.concat] on it:

```roc
greeting = "Hello and welcome to Roc"
subject = "Awesome Programmer"

# Evaluates to "Hello and welcome to Roc, Awesome Programmer!"
helloWorld =
    Str.withCapacity 45
    |> Str.concat greeting
    |> Str.concat ", "
    |> Str.concat subject
    |> Str.concat "!"
```

In general, if you plan to use [Str.concat] on an empty string, it will be faster to start with
[Str.withCapacity] than with `""`. Even if you don't know the exact capacity of the string, giving [withCapacity]
a higher value than ends up being necessary can help prevent reallocation and copying—at
the cost of using more memory than is necessary.

For more details on how the performance optimization works, see [Str.reserve].

#### reserve

**Type Annotation**

```roc
Str, U64 -> Str
```

**Description**

Increase a string's capacity by at least the given number of additional bytes.

This can improve the performance of string concatenation operations like [Str.concat] by
allocating extra capacity up front, which can prevent the need for reallocations and copies.
Consider the following example which does not use [Str.reserve]:

```roc
greeting = "Hello and welcome to Roc"
subject = "Awesome Programmer"

# Evaluates to "Hello and welcome to Roc, Awesome Programmer!"
helloWorld =
    greeting
    |> Str.concat ", "
    |> Str.concat subject
    |> Str.concat "!"
```

In this example:
1. We start with `greeting`, which has both a length and capacity of 24 (bytes).
2. `|> Str.concat ", "` will see that there isn't enough capacity to add 2 more bytes for the `", "`, so it will create a new heap allocation with enough bytes to hold both. (This probably will be more than 7 bytes, because when [Str] functions reallocate, they apply a multiplier to the exact capacity required. This makes it less likely that future realloctions will be needed. The multiplier amount is not specified, because it may change in future releases of Roc, but it will likely be around 1.5 to 2 times the exact capacity required.) Then it will copy the current bytes (`"Hello"`) into the new allocation, and finally concatenate the `", "` into the new allocation. The old allocation will then be deallocated because it's no longer referenced anywhere in the program.
3. `|> Str.concat subject` will again check if there is enough capacity in the string. If it doesn't find enough capacity once again, it will make a third allocation, copy the existing bytes (`"Hello, "`) into that third allocation, and then deallocate the second allocation because it's already no longer being referenced anywhere else in the program. (It may find enough capacity in this particular case, because the previous [Str.concat] allocated something like 1.5 to 2 times the necessary capacity in order to anticipate future concatenations like this...but if something longer than `"World"` were being concatenated here, it might still require further reallocation and copying.)
4. `|> Str.concat "!\n"` will repeat this process once more.

This process can have significant performance costs due to multiple reallocation of new strings, copying between old strings and new strings, and deallocation of immediately obsolete strings.

Here's a modified example which uses [Str.reserve] to eliminate the need for all that reallocation, copying, and deallocation.

```roc
helloWorld =
    greeting
    |> Str.reserve 21
    |> Str.concat ", "
    |> Str.concat subject
    |> Str.concat "!"
```

In this example:
1. We again start with `greeting`, which has both a length and capacity of 24 bytes.
2. `|> Str.reserve 21` will ensure that there is enough capacity in the string for an additional 21 bytes (to make room for `", "`, `"Awesome Programmer"`, and `"!"`). Since the current capacity is only 24, it will create a new 45-byte (24 + 21) heap allocation and copy the contents of the existing allocation (`greeting`) into it.
3. `|> Str.concat ", "` will concatenate `, ` to the string. No reallocation, copying, or deallocation will be necessary, because the string already has a capacity of 45 btytes, and `greeting` will only use 24 of them.
4. `|> Str.concat subject` will concatenate `subject` (`"Awesome Programmer"`) to the string. Again, no reallocation, copying, or deallocation will be necessary.
5. `|> Str.concat "!\n"` will concatenate `"!\n"` to the string, still without any reallocation, copying, or deallocation.

Here, [Str.reserve] prevented multiple reallocations, copies, and deallocations during the
[Str.concat] calls. Notice that it did perform a heap allocation before any [Str.concat] calls
were made, which means that using [Str.reserve] is not free! You should only use it if you actually
expect to make use of the extra capacity.

Ideally, you'd be able to predict exactly how many extra bytes of capacity will be needed, but this
may not always be knowable. When you don't know exactly how many bytes to reserve, you can often get better
performance by choosing a number of bytes that's too high, because a number that's too low could lead to reallocations. There's a limit to
this, of course; if you always give it ten times what it turns out to need, that could prevent
reallocations but will also waste a lot of memory!

If you plan to use [Str.reserve] on an empty string, it's generally better to use [Str.withCapacity] instead.

#### joinWith

**Type Annotation**

```roc
List Str, Str -> Str
```

**Description**

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

#### splitOn

**Type Annotation**

```roc
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.splitOn "1,2,3" "," == ["1","2","3"]
expect Str.splitOn "1,2,3" "" == ["1,2,3"]
```

#### repeat

**Type Annotation**

```roc
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 == ""
```

#### toUtf8

**Type Annotation**

```roc
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.splitOn].)
```roc
expect Str.toUtf8 "Roc" == [82, 111, 99]
expect Str.toUtf8 "鹏" == [233, 185, 143]
expect Str.toUtf8 "சி" == [224, 174, 154, 224, 174, 191]
expect Str.toUtf8 "🐦" == [240, 159, 144, 166]
```

#### fromUtf8

**Type Annotation**

```roc
List U8 -> Result Str [BadUtf8 Utf8ByteProblem 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.fromUtf8 [82, 111, 99] == Ok "Roc"
expect Str.fromUtf8 [233, 185, 143] == Ok "鹏"
expect Str.fromUtf8 [224, 174, 154, 224, 174, 191] == Ok "சி"
expect Str.fromUtf8 [240, 159, 144, 166] == Ok "🐦"
expect Str.fromUtf8 [] == Ok ""
expect Str.fromUtf8 [255] |> Result.isErr
```

#### startsWith

**Type Annotation**

```roc
Str, Str -> Bool
```

**Description**

Check if the given [Str] starts with a value.
```roc
expect Str.startsWith "ABC" "A" == Bool.true
expect Str.startsWith "ABC" "X" == Bool.false
```

#### endsWith

**Type Annotation**

```roc
Str, Str -> Bool
```

**Description**

Check if the given [Str] ends with a value.
```roc
expect Str.endsWith "ABC" "C" == Bool.true
expect Str.endsWith "ABC" "X" == Bool.false
```

#### trim

**Type Annotation**

```roc
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"
```

#### trimStart

**Type Annotation**

```roc
Str -> Str
```

**Description**

Return the [Str] with all whitespace removed from the beginning.
```roc
expect Str.trimStart "   Hello      \n\n" == "Hello      \n\n"
```

#### trimEnd

**Type Annotation**

```roc
Str -> Str
```

**Description**

Return the [Str] with all whitespace removed from the end.
```roc
expect Str.trimEnd "   Hello      \n\n" == "   Hello"
```

#### toDec

**Type Annotation**

```roc
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.toDec "10" == Ok 10dec
expect Str.toDec "-0.25" == Ok -0.25dec
expect Str.toDec "not a number" == Err InvalidNumStr
```

#### toF64

**Type Annotation**

```roc
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.toF64 "0.10" == Ok 0.10f64
expect Str.toF64 "not a number" == Err InvalidNumStr
```

#### toF32

**Type Annotation**

```roc
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.toF32 "0.10" == Ok 0.10f32
expect Str.toF32 "not a number" == Err InvalidNumStr
```

#### toU128

**Type Annotation**

```roc
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.toU128 "1500" == Ok 1500u128
expect Str.toU128 "0.1" == Err InvalidNumStr
expect Str.toU128 "-1" == Err InvalidNumStr
expect Str.toU128 "not a number" == Err InvalidNumStr
```

#### toI128

**Type Annotation**

```roc
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.toI128 "1500" == Ok 1500i128
expect Str.toI128 "-1" == Ok -1i128
expect Str.toI128 "0.1" == Err InvalidNumStr
expect Str.toI128 "not a number" == Err InvalidNumStr
```

#### toU64

**Type Annotation**

```roc
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.toU64 "1500" == Ok 1500u64
expect Str.toU64 "0.1" == Err InvalidNumStr
expect Str.toU64 "-1" == Err InvalidNumStr
expect Str.toU64 "not a number" == Err InvalidNumStr
```

#### toI64

**Type Annotation**

```roc
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.toI64 "1500" == Ok 1500i64
expect Str.toI64 "-1" == Ok -1i64
expect Str.toI64 "0.1" == Err InvalidNumStr
expect Str.toI64 "not a number" == Err InvalidNumStr
```

#### toU32

**Type Annotation**

```roc
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.toU32 "1500" == Ok 1500u32
expect Str.toU32 "0.1" == Err InvalidNumStr
expect Str.toU32 "-1" == Err InvalidNumStr
expect Str.toU32 "not a number" == Err InvalidNumStr
```

#### toI32

**Type Annotation**

```roc
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.toI32 "1500" == Ok 1500i32
expect Str.toI32 "-1" == Ok -1i32
expect Str.toI32 "0.1" == Err InvalidNumStr
expect Str.toI32 "not a number" == Err InvalidNumStr
```

#### toU16

**Type Annotation**

```roc
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.toU16 "1500" == Ok 1500u16
expect Str.toU16 "0.1" == Err InvalidNumStr
expect Str.toU16 "-1" == Err InvalidNumStr
expect Str.toU16 "not a number" == Err InvalidNumStr
```

#### toI16

**Type Annotation**

```roc
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.toI16 "1500" == Ok 1500i16
expect Str.toI16 "-1" == Ok -1i16
expect Str.toI16 "0.1" == Err InvalidNumStr
expect Str.toI16 "not a number" == Err InvalidNumStr
```

#### toU8

**Type Annotation**

```roc
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.toU8 "250" == Ok 250u8
expect Str.toU8 "-0.1" == Err InvalidNumStr
expect Str.toU8 "not a number" == Err InvalidNumStr
expect Str.toU8 "1500" == Err InvalidNumStr
```

#### toI8

**Type Annotation**

```roc
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.toI8 "-15" == Ok -15i8
expect Str.toI8 "150.00" == Err InvalidNumStr
expect Str.toI8 "not a number" == Err InvalidNumStr
```

#### countUtf8Bytes

**Type Annotation**

```roc
Str -> U64
```

**Description**

Gives the number of bytes in a [Str] value.
```roc
expect Str.countUtf8Bytes "Hello World" == 11
```

#### replaceEach

**Type Annotation**

```roc

    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.replaceEach "foo/bar/baz" "/" "_" == "foo_bar_baz"
expect Str.replaceEach "not here" "/" "_" == "not here"
```

#### replaceFirst

**Type Annotation**

```roc

    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.replaceFirst "foo/bar/baz" "/" "_" == "foo_bar/baz"
expect Str.replaceFirst "no slashes here" "/" "_" == "no slashes here"
```

#### replaceLast

**Type Annotation**

```roc

    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.replaceLast "foo/bar/baz" "/" "_" == "foo/bar_baz"
expect Str.replaceLast "no slashes here" "/" "_" == "no slashes here"
```

#### splitFirst

**Type Annotation**

```roc

    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.splitFirst "foo/bar/baz" "/" == Ok { before: "foo", after: "bar/baz" }
expect Str.splitFirst "no slashes here" "/" == Err NotFound
```

#### splitLast

**Type Annotation**

```roc

    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.splitLast "foo/bar/baz" "/" == Ok { before: "foo/bar", after: "baz" }
expect Str.splitLast "no slashes here" "/" == Err NotFound
```

#### walkUtf8WithIndex

**Type Annotation**

```roc

    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.walkUtf8WithIndex "ABC" [] f == [65, 66, 67]
```

#### walkUtf8

**Type Annotation**

```roc

    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
sumOfUtf8Bytes =
    Str.walkUtf8 "Hello, World!" 0 \total, byte ->
        total + byte

expect sumOfUtf8Bytes == 105
```

#### releaseExcessCapacity

**Type Annotation**

```roc
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.

#### withPrefix

**Type Annotation**

```roc
Str, Str -> Str
```

**Description**

Adds a prefix to the given [Str].
```roc
expect Str.withPrefix "Awesome" "Roc" == "RocAwesome"
```

#### contains

**Type Annotation**

```roc
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" ""
```

#### dropPrefix

**Type Annotation**

```roc
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.dropPrefix "bar" "foo" == "bar"
expect Str.dropPrefix "foobar" "foo" == "bar"
```

#### dropSuffix

**Type Annotation**

```roc
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.dropSuffix "bar" "foo" == "bar"
expect Str.dropSuffix "barfoo" "foo" == "bar"
```

### Num

#### Num

**Type Annotation**

**Description**

Represents a number that could be either an [Int] or a [Frac].

This is useful for functions that can work on either, for example [Num.add], whose type is:
```roc
add : Num a, Num a -> Num a
```
The number 1.5 technically has the type `Num (Fraction *)`, so when you pass
two of them to [Num.add], the answer you get is `3.0 : Num (Fraction *)`.

Similarly, the number 0x1 (that is, the integer 1 in hexadecimal notation)
technically has the type `Num (Integer *)`, so when you pass two of them to
[Num.add], the answer you get is `2 : Num (Integer *)`.

The type [`Frac a`](#Frac) is defined to be an alias for `Num (Fraction a)`,
so `3.0 : Num (Fraction *)` is the same value as `3.0 : Frac *`.
Similarly, the type [`Int a`](#Int) is defined to be an alias for
`Num (Integer a)`, so `2 : Num (Integer *)` is the same value as
`2 : Int *`.

In this way, the [Num] type makes it possible to have `1 + 0x1` return
`2 : Int *` and `1.5 + 1.5` return `3.0 : Frac`.

## Number Literals

Number literals without decimal points (like `0`, `4` or `360`)
have the type `Num *` at first, but usually end up taking on
a more specific type based on how they're used.

For example, in `(1 + List.len myList)`, the `1` has the type `Num *` at first,
but because `List.len` returns a `U64`, the `1` ends up changing from
`Num *` to the more specific `U64`, and the expression as a whole
ends up having the type `U64`.

Sometimes number literals don't become more specific. For example,
the `Num.toStr` function has the type `Num * -> Str`. This means that
when calling `Num.toStr (5 + 6)`, the expression `(5 + 6)`
still has the type `Num *`. When this happens, `Num *` defaults to
being an [I64] - so this addition expression would overflow
if either 5 or 6 were replaced with a number big enough to cause
addition overflow on an [I64] value.

If this default of [I64] is not big enough for your purposes,
you can add an `i128` to the end of the number literal, like so:
```roc
Num.toStr 5_000_000_000i128
```
This `i128` suffix specifies that you want this number literal to be
an [I128] instead of a `Num *`. All the other numeric types have
suffixes just like `i128`; here are some other examples:

* `215u8` is a `215` value of type [U8]
* `76.4f32` is a `76.4` value of type [F32]
* `123.45dec` is a `123.45` value of type [Dec]

In practice, these are rarely needed. It's most common to write
number literals without any suffix.

#### Int

**Type Annotation**

**Description**

A fixed-size integer - that is, a number with no fractional component.

Integers come in two flavors: signed and unsigned. Signed integers can be
negative ("signed" refers to how they can incorporate a minus sign),
whereas unsigned integers cannot be negative.

Since integers have a fixed size, the size you choose determines both the
range of numbers it can represent, and also how much memory it takes up.

[U8] is an an example of an integer. It is an unsigned [Int] that takes up 8 bits
(aka 1 byte) in memory. The `U` is for Unsigned and the 8 is for 8 bits.
Because it has 8 bits to work with, it can store 256 numbers (2^8),
and because it is unsigned, its min value is 0. This means the 256 numbers
it can store range from 0 to 255.

[I8] is a signed integer that takes up 8 bits. The `I` is for Integer, since
integers in mathematics are signed by default. Because it has 8 bits just
like [U8], it can store 256 numbers (still 2^8), but because it is signed,
the range is different. Its 256 numbers range from -128 to 127.

Here are some other examples:

* [U16] is like [U8], except it takes up 16 bits in memory. It can store 65,536 numbers (2^16), ranging from 0 to 65,536.
* [I16] is like [U16], except it is signed. It can still store the same 65,536 numbers (2^16), ranging from -32,768 to 32,767.

This pattern continues up to [U128] and [I128].

## Performance Details

In general, using smaller numeric sizes means your program will use less memory.
However, if a mathematical operation results in an answer that is too big
or too small to fit in the size available for that answer (which is typically
the same size as the inputs), then you'll get an overflow error.

As such, minimizing memory usage without causing overflows involves choosing
number sizes based on your knowledge of what numbers you expect your program
to encounter at runtime.

Minimizing memory usage does not imply maximum runtime speed!
CPUs are typically fastest at performing integer operations on integers that
are the same size as that CPU's native machine word size. That means a 64-bit
CPU is typically fastest at executing instructions on [U64] and [I64] values,
whereas a 32-bit CPU is typically fastest on [U32] and [I32] values.

Putting these factors together, here are some reasonable guidelines for optimizing performance through integer size choice:

* Start by deciding if this integer should allow negative numbers, and choose signed or unsigned accordingly.
* Next, think about the range of numbers you expect this number to hold. Choose the smallest size you will never expect to overflow, no matter the inputs your program receives. (Validating inputs for size, and presenting the user with an error if they are too big, can help guard against overflow.)
* Finally, if a particular numeric calculation is running too slowly, you can try experimenting with other number sizes. This rarely makes a meaningful difference, but some processors can operate on different number sizes at different speeds.

All number literals without decimal points are compatible with [Int] values.

You can optionally put underscores in your [Int] literals.
They have no effect on the number's value, but can make large numbers easier to read.
```roc
1_000_000
```
Integers come in two flavors: *signed* and *unsigned*.

* *Unsigned* integers can never be negative. The lowest value they can hold is zero.
* *Signed* integers can be negative.

Integers also come in different sizes. Choosing a size depends on your performance
needs and the range of numbers you need to represent. At a high level, the
general trade-offs are:

* Larger integer sizes can represent a wider range of numbers. If you absolutely need to represent numbers in a certain range, make sure to pick an integer size that can hold them!
* Smaller integer sizes take up less memory. These savings rarely matter in variables and function arguments, but the sizes of integers that you use in data structures can add up. This can also affect whether those data structures fit in [cache lines](https://en.wikipedia.org/wiki/CPU_cache#Cache_performance), which can be a performance bottleneck.
* Certain CPUs work faster on some numeric sizes than others. If the CPU is taking too long to run numeric calculations, you may find a performance improvement by experimenting with numeric sizes that are larger than otherwise necessary. However, in practice, doing this typically degrades overall performance, so be careful to measure properly!

Here are the different fixed size integer types:

| Range                                                  | Type  | Size     |
|--------------------------------------------------------|-------|----------|
| `                                                -128` | [I8]  | 1 Byte   |
| `                                                 127` |       |          |
|--------------------------------------------------------|-------|----------|
| `                                                   0` | [U8]  | 1 Byte   |
| `                                                 255` |       |          |
|--------------------------------------------------------|-------|----------|
| `                                             -32_768` | [I16] | 2 Bytes  |
| `                                              32_767` |       |          |
|--------------------------------------------------------|-------|----------|
| `                                                   0` | [U16] | 2 Bytes  |
| `                                              65_535` |       |          |
|--------------------------------------------------------|-------|----------|
| `                                      -2_147_483_648` | [I32] | 4 Bytes  |
| `                                       2_147_483_647` |       |          |
|--------------------------------------------------------|-------|----------|
| `                                                   0` | [U32] | 4 Bytes  |
| ` (over 4 billion)                      4_294_967_295` |       |          |
|--------------------------------------------------------|-------|----------|
| `                          -9_223_372_036_854_775_808` | [I64] | 8 Bytes  |
| `                           9_223_372_036_854_775_807` |       |          |
|--------------------------------------------------------|-------|----------|
| `                                                   0` | [U64] | 8 Bytes  |
| ` (over 18 quintillion)    18_446_744_073_709_551_615` |       |          |
|--------------------------------------------------------|-------|----------|
| `-170_141_183_460_469_231_731_687_303_715_884_105_728` | [I128]| 16 Bytes |
| ` 170_141_183_460_469_231_731_687_303_715_884_105_727` |       |          |
|--------------------------------------------------------|-------|----------|
| ` (over 340 undecillion)                            0` | [U128]| 16 Bytes |
| ` 340_282_366_920_938_463_463_374_607_431_768_211_455` |       |          |

If any operation would result in an [Int] that is either too big
or too small to fit in that range (e.g. calling `Num.maxI32 + 1`),
then the operation will *overflow*. When an overflow occurs, the program will crash.

As such, it's very important to design your code not to exceed these bounds!
If you need to do math outside these bounds, consider using a larger numeric size.

#### Frac

**Type Annotation**

**Description**

A fixed-size number with a fractional component.

Roc fractions come in two flavors: fixed-point base-10 and floating-point base-2.

* [Dec] is a 128-bit [fixed-point](https://en.wikipedia.org/wiki/Fixed-point_arithmetic) base-10 number. It's a great default choice, especially when precision is important - for example when representing currency. With [Dec], `0.1 + 0.2` returns `0.3`. [Dec] has 18 decimal places of precision and a range from `-170_141_183_460_469_231_731.687303715884105728` to `170_141_183_460_469_231_731.687303715884105727`.
* [F64] and [F32] are [floating-point](https://en.wikipedia.org/wiki/Floating-point_arithmetic) base-2 numbers. They sacrifice precision for lower memory usage and improved performance on some operations. This makes them a good fit for representing graphical coordinates. With [F64], `0.1 + 0.2` returns `0.30000000000000004`.

If you don't specify a type, Roc will default to using [Dec] because it's
the least error-prone overall. For example, suppose you write this:
```roc
wasItPrecise = 0.1 + 0.2 == 0.3
```
The value of `wasItPrecise` here will be `Bool.true`, because Roc uses [Dec]
by default when there are no types specified.

In contrast, suppose we use `f32` or `f64` for one of these numbers:
```roc
wasItPrecise = 0.1f64 + 0.2 == 0.3
```
Here, `wasItPrecise` will be `Bool.false` because the entire calculation will have
been done in a base-2 floating point calculation, which causes noticeable
precision loss in this case.

The floating-point numbers ([F32] and [F64]) also have three values which
are not ordinary [finite numbers](https://en.wikipedia.org/wiki/Finite_number).
They are:
* ∞ ([infinity](https://en.wikipedia.org/wiki/Infinity))
* -∞ (negative infinity)
* *NaN* ([not a number](https://en.wikipedia.org/wiki/NaN))

These values are different from ordinary numbers in that they only occur
when a floating-point calculation encounters an error. For example:
* Dividing a positive [F64] by `0.0` returns ∞.
* Dividing a negative [F64] by `0.0` returns -∞.
* Dividing a [F64] of `0.0` by `0.0` returns [*NaN*](Num.isNaN).

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.

There's no literal syntax for these error values, but you can check to see if
you ended up with one of them by using #isNaN, #isFinite, and #isInfinite.
Whenever a function in this module could return one of these values, that
possibility is noted in the function's documentation.

## Performance Details

On typical modern CPUs, performance is similar between [Dec], [F64], and [F32]
for addition and subtraction. For example, [F32] and [F64] do addition using
a single CPU floating-point addition instruction, which typically takes a
few clock cycles to complete. In contrast, [Dec] does addition using a few
CPU integer arithmetic instructions, each of which typically takes only one
clock cycle to complete. Exact numbers will vary by CPU, but they should be
similar overall.

[Dec] is significantly slower for multiplication and division. It not only
needs to do more arithmetic instructions than [F32] and [F64] do, but also
those instructions typically take more clock cycles to complete.

With [Num.sqrt] and trigonometry functions like [Num.cos], there is
an even bigger performance difference. [F32] and [F64] can do these in a
single instruction, whereas [Dec] needs entire custom procedures - which use
loops and conditionals. If you need to do performance-critical trigonometry
or square roots, either [F64] or [F32] is probably a better choice than the
usual default choice of [Dec], despite the precision problems they bring.

#### Signed128

**Type Annotation**

#### Signed64

**Type Annotation**

#### Signed32

**Type Annotation**

#### Signed16

**Type Annotation**

#### Signed8

**Type Annotation**

#### Unsigned128

**Type Annotation**

#### Unsigned64

**Type Annotation**

#### Unsigned32

**Type Annotation**

#### Unsigned16

**Type Annotation**

#### Unsigned8

**Type Annotation**

#### Integer

**Type Annotation**

#### I128

**Type Annotation**

#### I64

**Type Annotation**

#### I32

**Type Annotation**

#### I16

**Type Annotation**

#### I8

**Type Annotation**

**Description**

A signed 8-bit integer, ranging from -128 to 127

#### U128

**Type Annotation**

#### U64

**Type Annotation**

#### U32

**Type Annotation**

#### U16

**Type Annotation**

#### U8

**Type Annotation**

#### Decimal

**Type Annotation**

#### Binary64

**Type Annotation**

#### Binary32

**Type Annotation**

#### FloatingPoint

**Type Annotation**

#### F64

**Type Annotation**

**Description**

A 64-bit [IEEE 754 binary floating-point number](https://en.wikipedia.org/wiki/IEEE_754).

[F64] represents decimal numbers less precisely than [Dec] does, but operations on it
can be faster because CPUs have hardware-level support for [F64] but not [Dec]. There
are other tradeoffs between the two, such as:
* [Dec] has a fixed number of digits it can represent before the decimal point, and a fixed number it can represent after the decimal point. In contrast, [F64]'s decimal point can "float"—which conceptually means if you don't need many digits before the decimal point, you can get more digits of precision afterwards (and vice versa).
* [Dec] represents its number internally in [base-10](https://en.wikipedia.org/wiki/Decimal), whereas [F64] uses [base-2](https://en.wikipedia.org/wiki/Binary_number). This can lead to imprecise answers like `0.1 + 0.2` returning `0.3` for [Dec] and `0.30000000000000004` for [F64]. This is not a bug; rather, it's a consequence of [F64]'s base-2 representation.
* [Dec] always gives a precise answer (or an error), whereas [F64] can lose precision. For example, increasing a very large [F64] number (using addition, perhaps) can result in the whole number portion being incorrect. `1234567890123456789 + 100` correctly results in a number ending in `889` for `Dec`, but results in a number ending `800` in [F64] due to precision loss.

#### F32

**Type Annotation**

**Description**

A 32-bit [IEEE 754 binary floating-point number](https://en.wikipedia.org/wiki/IEEE_754).

This works just like [F64] (see its docs for a comparison with [Dec]) except it's smaller.
That in turn means it takes up less memory, but can store smaller numbers (and becomes imprecise
more easily than [F64] does).

#### Dec

**Type Annotation**

**Description**

A [decimal](https://en.wikipedia.org/wiki/Decimal) number.

[Dec] is a more precise way to represent decimal numbers (like currency) than [F32] and [F64]
are, because [Dec] is represented in memory as base-10. In contrast, [F64] and [F32]
are [base-2](https://en.wikipedia.org/wiki/Binary_number) in memory, which can lead to decimal
precision loss even when doing addition and subtraction. For example, when
using [F64], `0.1 + 0.2` returns 0.30000000000000004,
whereas when using [Dec], `0.1 + 0.2` returns 0.3.

Under the hood, a [Dec] is an [I128], and operations on it perform
[base-10 fixed-point arithmetic](https://en.wikipedia.org/wiki/Fixed-point_arithmetic)
with 18 decimal places of precision.

This means a [Dec] can represent whole numbers up to slightly over 170
quintillion, along with 18 decimal places. (To be precise, it can store
numbers between `-170_141_183_460_469_231_731.687303715884105728`
and `170_141_183_460_469_231_731.687303715884105727`.) Why 18
decimal places? It's the highest number of decimal places where you can
still convert any [U64] to a [Dec] without losing information.

There are some use cases where [F64] and [F32] can be better choices than [Dec]
despite their issues with base-10 numbers. For example, in graphical applications
they can be a better choice for representing coordinates because they take up
less memory, certain relevant calculations run faster (see performance
details, below), and base-10 generally isn't as big a concern when
dealing with screen coordinates as it is when dealing with currency.

Another scenario where [F64] can be a better choice than [Dec] is when representing
extremely small numbers. The smallest positive [F64] that can be represented without precision
loss is 2^(−1074), which is about 5 * 10^(-324). Here is that number next to the smallest
[Dec] that can be represented:

* Smallest [F64]: 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005
* Smallest [Dec]: 0.000000000000000001

This is because [floating-point](https://en.wikipedia.org/wiki/Floating-point_arithmetic) numbers
like [F64] can gain more digits of precision after the `.` when they aren't using as many digits
before the `.` - and this applies the most if the digit before `.` is `0`. So whereas [Dec] always
has 18 digits after the `.`, the number of digits after the `.` that [F32] can [F64] can represent
without precision loss depends on what comes before it.

## Performance Details

CPUs have dedicated instructions for many [F32] and [F64] operations, but none for [Dec].
Internally, [Dec] is represented as a 128-bit integer and uses multiple instructions to
perform fractional operations. This gives [F32] and [F64] performance advantages
for many operations.

Here's a comparison of about how long [Dec] takes to perform a given operation compared to [F64],
based on benchmarks on an [M1](https://en.wikipedia.org/wiki/Apple_M1) CPU:
* [add]  0.6x
* [sub]  0.6x
* [mul]  15x
* [div]  55x
* [sin]  3.9x
* [cos]  3.6x
* [tan]  2.3x
* [asin] 1.8x
* [acos] 1.7x
* [atan] 1.7x

Keep in mind that arithmetic instructions are basically [the fastest thing a CPU does](http://norvig.com/21-days.html#answers),
so (for example) a network request that takes 10 milliseconds to complete would go on this
list as about 10000000x. So these performance differences might be more or less noticeable than
the base-10 representation differences depending on the use case.

#### e

**Type Annotation**

```roc
Frac *
```

**Description**

Euler's number (e)

#### pi

**Type Annotation**

```roc
Frac *
```

**Description**

Archimedes' constant (π)

#### tau

**Type Annotation**

```roc
Frac *
```

**Description**

Circle constant (τ)

#### toStr

**Type Annotation**

```roc
Num * -> Str
```

**Description**

Convert a number to a [Str].

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


#### intCast

**Type Annotation**

```roc
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.intCast 255u8
```

In the case of downsizing, information is lost:

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


#### compare

**Type Annotation**

```roc

    Num a, 
    Num a
    -> 
        [
            LT,
            EQ,
            GT
        ]
```

#### isLt

**Type Annotation**

```roc
Num a, Num a -> Bool
```

**Description**

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

`a < b` is shorthand for `Num.isLt a b`.

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

#### isGt

**Type Annotation**

```roc
Num a, Num a -> Bool
```

**Description**

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

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

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

#### isLte

**Type Annotation**

```roc
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.isLte a b`.

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

#### isGte

**Type Annotation**

```roc
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.isGte a b`.

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

#### isApproxEq

**Type Annotation**

```roc

    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.isApproxEq a b == Num.isApproxEq b a`

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

#### isZero

**Type Annotation**

```roc
Num a -> Bool
```

**Description**

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

#### isEven

**Type Annotation**

```roc
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

#### isOdd

**Type Annotation**

```roc
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

#### isPositive

**Type Annotation**

```roc
Num a -> Bool
```

**Description**

Positive numbers are greater than `0`.

#### isNegative

**Type Annotation**

```roc
Num a -> Bool
```

**Description**

Negative numbers are less than `0`.

#### toFrac

**Type Annotation**

```roc
Num * -> Frac *
```

#### isNaN

**Type Annotation**

```roc
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.isNaN (0 / 0)
```

#### isInfinite

**Type Annotation**

```roc
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.isInfinite (1 / 0)

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

#### isFinite

**Type Annotation**

```roc
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.isFinite 42
```

#### abs

**Type Annotation**

```roc
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.minI64] or [Num.minI32]) 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.

#### absDiff

**Type Annotation**

```roc
Num a, Num a -> Num a
```

**Description**

Returns the absolute difference between two numbers.

```roc
Num.absDiff 5 3

Num.absDiff -3 5

Num.absDiff 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

**Type Annotation**

```roc
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 `\someNum -> 0 - someNum` 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.minI64] or [Num.minI32]) 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

**Type Annotation**

```roc
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

**Type Annotation**

```roc
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

**Type Annotation**

```roc
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

**Type Annotation**

```roc
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

**Type Annotation**

```roc
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

**Type Annotation**

```roc
Frac a -> Frac a
```

#### cos

**Type Annotation**

```roc
Frac a -> Frac a
```

#### tan

**Type Annotation**

```roc
Frac a -> Frac a
```

#### asin

**Type Annotation**

```roc
Frac a -> Frac a
```

#### acos

**Type Annotation**

```roc
Frac a -> Frac a
```

#### atan

**Type Annotation**

```roc
Frac a -> Frac a
```

#### sqrt

**Type Annotation**

```roc
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.isNaN).
* Passing [*NaN*](Num.isNaN) or -∞ also returns [*NaN*](Num.isNaN).
* 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
```

#### sqrtChecked

**Type Annotation**

```roc
Frac a -> Result (Frac a) [SqrtOfNegative]
```

#### log

**Type Annotation**

```roc
Frac a -> Frac a
```

**Description**

Natural logarithm

#### logChecked

**Type Annotation**

```roc
Frac a -> Result (Frac a) [LogNeedsPositive]
```

#### div

**Type Annotation**

```roc
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.isNaN).

> 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 #toDec.
```roc
5.0 / 7.0

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

#### divChecked

**Type Annotation**

```roc
Frac a, Frac a -> Result (Frac a) [DivByZero]
```

#### divCeil

**Type Annotation**

```roc
Int a, Int a -> Int a
```

#### divCeilChecked

**Type Annotation**

```roc
Int a, Int a -> Result (Int a) [DivByZero]
```

#### divTrunc

**Type Annotation**

```roc
Int a, Int a -> Int a
```

**Description**

Divides two integers, truncating the result towards zero.

`a // b` is shorthand for `Num.divTrunc 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.divTrunc 5 7

8 // -3

Num.divTrunc 8 -3
```

#### divTruncChecked

**Type Annotation**

```roc
Int a, Int a -> Result (Int a) [DivByZero]
```

#### rem

**Type Annotation**

```roc
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
```

#### remChecked

**Type Annotation**

```roc
Int a, Int a -> Result (Int a) [DivByZero]
```

#### isMultipleOf

**Type Annotation**

```roc
Int a, Int a -> Bool
```

#### bitwiseAnd

**Type Annotation**

```roc
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.

#### bitwiseXor

**Type Annotation**

```roc
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.

#### bitwiseOr

**Type Annotation**

```roc
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.

#### bitwiseNot

**Type Annotation**

```roc
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.

#### shiftLeftBy

**Type Annotation**

```roc
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
shiftLeftBy 0b0000_0011 2 == 0b0000_1100

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

#### shiftRightBy

**Type Annotation**

```roc
Int a, U8 -> Int a
```

**Description**

Bitwise arithmetic shift of a number by another

The most significant bits are copied from the current.
```roc
shiftRightBy 0b0000_1100 2 == 0b0000_0011

0b0001_0100 |> shiftRightBy 2 == 0b0000_0101

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

#### shiftRightZfBy

**Type Annotation**

```roc
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
shiftRightZfBy 0b0010_1000 2 == 0b0000_1010

0b0010_1000 |> shiftRightZfBy 2 == 0b0000_1010

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

#### round

**Type Annotation**

```roc
Frac * -> Int *
```

**Description**

Round off the given fraction to the nearest integer.

#### floor

**Type Annotation**

```roc
Frac * -> Int *
```

#### ceiling

**Type Annotation**

```roc
Frac * -> Int *
```

#### pow

**Type Annotation**

```roc
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.powInt]

#### powInt

**Type Annotation**

```roc
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.

#### countLeadingZeroBits

**Type Annotation**

```roc
Int a -> U8
```

**Description**

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

```roc
Num.countLeadingZeroBits 0b0001_1100u8

3

Num.countLeadingZeroBits 0b0000_0000u8

8
```

#### countTrailingZeroBits

**Type Annotation**

```roc
Int a -> U8
```

**Description**

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

```roc
Num.countTrailingZeroBits 0b0001_1100u8

2

Num.countTrailingZeroBits 0b0000_0000u8

8
```

#### countOneBits

**Type Annotation**

```roc
Int a -> U8
```

**Description**

Counts the number of set bits in an integer.

```roc
Num.countOneBits 0b0001_1100u8

3

Num.countOneBits 0b0000_0000u8

0
```

#### addWrap

**Type Annotation**

```roc
Int range, Int range -> Int range
```

#### addSaturated

**Type Annotation**

```roc
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, `addSaturated x y` will
yield 255, the maximum value of a `U8`.

#### addChecked

**Type Annotation**

```roc
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`.

#### subWrap

**Type Annotation**

```roc
Int range, Int range -> Int range
```

#### subSaturated

**Type Annotation**

```roc
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, `subSaturated x y` will
yield 0, the minimum value of a `U8`.

#### subChecked

**Type Annotation**

```roc
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`.

#### mulWrap

**Type Annotation**

```roc
Int range, Int range -> Int range
```

#### mulSaturated

**Type Annotation**

```roc
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.

#### mulChecked

**Type Annotation**

```roc
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`.

#### minI8

**Type Annotation**

```roc
I8
```

**Description**

Returns the lowest number that can be stored in an [I8] without underflowing
its available memory and crashing.

For reference, this number is `-128`.

Note that the positive version of this number is larger than [Num.maxI8],
which means if you call [Num.abs] on [Num.minI8], it will overflow and crash!

#### maxI8

**Type Annotation**

```roc
I8
```

**Description**

Returns the highest number that can be stored in an [I8] without overflowing
its available memory and crashing.

For reference, this number is `127`.

Note that this is smaller than the positive version of [Num.minI8],
which means if you call [Num.abs] on [Num.minI8], it will overflow and crash!

#### minU8

**Type Annotation**

```roc
U8
```

**Description**

Returns the lowest number that can be stored in a [U8] without underflowing
its available memory and crashing.

For reference, this number is zero, because [U8] is
[unsigned](https://en.wikipedia.org/wiki/Signed_number_representations),
and zero is the lowest unsigned number.
Unsigned numbers cannot be negative.

#### maxU8

**Type Annotation**

```roc
U8
```

**Description**

Returns the highest number that can be stored in a [U8] without overflowing
its available memory and crashing.

For reference, this number is `255`.

#### minI16

**Type Annotation**

```roc
I16
```

**Description**

Returns the lowest number that can be stored in an [I16] without underflowing
its available memory and crashing.

For reference, this number is `-32_768`.

Note that the positive version of this number is larger than [Num.maxI16],
which means if you call [Num.abs] on [Num.minI16], it will overflow and crash!

#### maxI16

**Type Annotation**

```roc
I16
```

**Description**

Returns the highest number that can be stored in an [I16] without overflowing
its available memory and crashing.

For reference, this number is `32_767`.

Note that this is smaller than the positive version of [Num.minI16],
which means if you call [Num.abs] on [Num.minI16], it will overflow and crash!

#### minU16

**Type Annotation**

```roc
U16
```

**Description**

Returns the lowest number that can be stored in a [U16] without underflowing
its available memory and crashing.

For reference, this number is zero, because [U16] is
[unsigned](https://en.wikipedia.org/wiki/Signed_number_representations),
and zero is the lowest unsigned number.
Unsigned numbers cannot be negative.

#### maxU16

**Type Annotation**

```roc
U16
```

**Description**

Returns the highest number that can be stored in a [U16] without overflowing
its available memory and crashing.

For reference, this number is `65_535`.

#### minI32

**Type Annotation**

```roc
I32
```

**Description**

Returns the lowest number that can be stored in an [I32] without underflowing
its available memory and crashing.

For reference, this number is `-2_147_483_648`.

Note that the positive version of this number is larger than [Num.maxI32],
which means if you call [Num.abs] on [Num.minI32], it will overflow and crash!

#### maxI32

**Type Annotation**

```roc
I32
```

**Description**

Returns the highest number that can be stored in an [I32] without overflowing
its available memory and crashing.

For reference, this number is `2_147_483_647`,
which is over 2 million.

Note that this is smaller than the positive version of [Num.minI32],
which means if you call [Num.abs] on [Num.minI32], it will overflow and crash!

#### minU32

**Type Annotation**

```roc
U32
```

**Description**

Returns the lowest number that can be stored in a [U32] without underflowing
its available memory and crashing.

For reference, this number is zero, because [U32] is
[unsigned](https://en.wikipedia.org/wiki/Signed_number_representations),
and zero is the lowest unsigned number.
Unsigned numbers cannot be negative.

#### maxU32

**Type Annotation**

```roc
U32
```

**Description**

Returns the highest number that can be stored in a [U32] without overflowing
its available memory and crashing.

For reference, this number is `4_294_967_295`.

#### minI64

**Type Annotation**

```roc
I64
```

**Description**

Returns the lowest number that can be stored in an [I64] without underflowing
its available memory and crashing.

For reference, this number is `-9_223_372_036_854_775_808`,
which is under 9 quintillion.

Note that the positive version of this number is larger than [Num.maxI64],
which means if you call [Num.abs] on [Num.minI64], it will overflow and crash!

#### maxI64

**Type Annotation**

```roc
I64
```

**Description**

Returns the highest number that can be stored in an [I64] without overflowing
its available memory and crashing.

For reference, this number is `9_223_372_036_854_775_807`,
which is over 9 quintillion.

Note that this is smaller than the positive version of [Num.minI64],
which means if you call [Num.abs] on [Num.minI64], it will overflow and crash!

#### minU64

**Type Annotation**

```roc
U64
```

**Description**

Returns the lowest number that can be stored in a [U64] without underflowing
its available memory and crashing.

For reference, this number is zero, because [U64] is
[unsigned](https://en.wikipedia.org/wiki/Signed_number_representations),
and zero is the lowest unsigned number.
Unsigned numbers cannot be negative.

#### maxU64

**Type Annotation**

```roc
U64
```

**Description**

Returns the highest number that can be stored in a [U64] without overflowing
its available memory and crashing.

For reference, this number is `18_446_744_073_709_551_615`,
which is over 18 quintillion.

#### minI128

**Type Annotation**

```roc
I128
```

**Description**

Returns the lowest number that can be stored in an [I128] without underflowing
its available memory and crashing.

For reference, this number is `-170_141_183_460_469_231_731_687_303_715_884_105_728`.
which is under 170 undecillion.

Note that the positive version of this number is larger than [Num.maxI128],
which means if you call [Num.abs] on [Num.minI128], it will overflow and crash!

#### maxI128

**Type Annotation**

```roc
I128
```

**Description**

Returns the highest number that can be stored in an [I128] without overflowing
its available memory and crashing.

For reference, this number is `170_141_183_460_469_231_731_687_303_715_884_105_727`,
which is over 170 undecillion.

Note that this is smaller than the positive version of [Num.minI128],
which means if you call [Num.abs] on [Num.minI128], it will overflow and crash!

#### minU128

**Type Annotation**

```roc
U128
```

**Description**

Returns the lowest number that can be stored in a [U128] without underflowing
its available memory and crashing.

For reference, this number is zero, because [U128] is
[unsigned](https://en.wikipedia.org/wiki/Signed_number_representations),
and zero is the lowest unsigned number.
Unsigned numbers cannot be negative.

#### maxU128

**Type Annotation**

```roc
U128
```

**Description**

Returns the highest number that can be stored in a [U128] without overflowing
its available memory and crashing.

For reference, this number is `340_282_366_920_938_463_463_374_607_431_768_211_455`,
which is over 340 undecillion.

#### minF32

**Type Annotation**

```roc
F32
```

#### maxF32

**Type Annotation**

```roc
F32
```

#### minF64

**Type Annotation**

```roc
F64
```

#### maxF64

**Type Annotation**

```roc
F64
```

#### toI8

**Type Annotation**

```roc
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.

#### toI16

**Type Annotation**

```roc
Int * -> I16
```

#### toI32

**Type Annotation**

```roc
Int * -> I32
```

#### toI64

**Type Annotation**

```roc
Int * -> I64
```

#### toI128

**Type Annotation**

```roc
Int * -> I128
```

#### toU8

**Type Annotation**

```roc
Int * -> U8
```

#### toU16

**Type Annotation**

```roc
Int * -> U16
```

#### toU32

**Type Annotation**

```roc
Int * -> U32
```

#### toU64

**Type Annotation**

```roc
Int * -> U64
```

#### toU128

**Type Annotation**

```roc
Int * -> U128
```

#### toF32

**Type Annotation**

```roc
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.

#### toF64

**Type Annotation**

```roc
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.

#### toI8Checked

**Type Annotation**

```roc
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`.

#### toI16Checked

**Type Annotation**

```roc
Int * -> Result I16 [OutOfBounds]
```

#### toI32Checked

**Type Annotation**

```roc
Int * -> Result I32 [OutOfBounds]
```

#### toI64Checked

**Type Annotation**

```roc
Int * -> Result I64 [OutOfBounds]
```

#### toI128Checked

**Type Annotation**

```roc
Int * -> Result I128 [OutOfBounds]
```

#### toU8Checked

**Type Annotation**

```roc
Int * -> Result U8 [OutOfBounds]
```

#### toU16Checked

**Type Annotation**

```roc
Int * -> Result U16 [OutOfBounds]
```

#### toU32Checked

**Type Annotation**

```roc
Int * -> Result U32 [OutOfBounds]
```

#### toU64Checked

**Type Annotation**

```roc
Int * -> Result U64 [OutOfBounds]
```

#### toU128Checked

**Type Annotation**

```roc
Int * -> Result U128 [OutOfBounds]
```

#### toF32Checked

**Type Annotation**

```roc
Num * -> Result F32 [OutOfBounds]
```

#### toF64Checked

**Type Annotation**

```roc
Num * -> Result F64 [OutOfBounds]
```

#### withoutDecimalPoint

**Type Annotation**

```roc
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.

#### withDecimalPoint

**Type Annotation**

```roc
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.

#### f32ToParts

**Type Annotation**

```roc

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

**Description**

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

#### f64ToParts

**Type Annotation**

```roc

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

**Description**

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

#### f32FromParts

**Type Annotation**

```roc
    
    {
        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.

#### f64FromParts

**Type Annotation**

```roc
    
    {
        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.

#### nanF32

**Type Annotation**

```roc
F32
```

**Description**

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

#### nanF64

**Type Annotation**

```roc
F64
```

**Description**

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

#### infinityF32

**Type Annotation**

```roc
F32
```

**Description**

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

#### infinityF64

**Type Annotation**

```roc
F64
```

**Description**

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

### Bool

#### Eq

**Type Annotation**

```roc
implements
    isEq : 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 `isEq 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.

#### Bool

**Type Annotation**

**Description**

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

#### true

**Type Annotation**

```roc
Bool
```

**Description**

The boolean true value.

#### false

**Type Annotation**

```roc
Bool
```

**Description**

The boolean false value.

#### and

**Type Annotation**

```roc
Bool, Bool -> Bool
```

**Description**

Returns `Bool.true` when both inputs are `Bool.true`. This is equivalent to
the logic [AND](https://en.wikipedia.org/wiki/Logical_conjunction)
gate. The infix operator `&&` can also be used as shorthand for
`Bool.and`.

```roc
expect (Bool.and Bool.true Bool.true) == Bool.true
expect (Bool.true && Bool.true) == Bool.true
expect (Bool.false && Bool.true) == Bool.false
expect (Bool.true && Bool.false) == Bool.false
expect (Bool.false && Bool.false) == Bool.false
```

## Performance Details

In Roc the `&&` and `||` work the same way as any
other function. However, in some languages `&&` and `||` are special-cased.
In these languages the compiler will skip evaluating the expression after the
first operator under certain circumstances. For example an expression like
`enablePets && likesDogs user` would compile to.
```roc
if enablePets then
    likesDogs user
else
    Bool.false
```
Roc does not do this because conditionals like `if` and `when` have a
performance cost. Calling a function can sometimes be faster across the board
than doing an `if` to decide whether to skip calling it.

#### or

**Type Annotation**

```roc
Bool, Bool -> Bool
```

**Description**

Returns `Bool.true` when either input is a `Bool.true`. This is equivalent to
the logic [OR](https://en.wikipedia.org/wiki/Logical_disjunction) gate.
The infix operator `||` can also be used as shorthand for `Bool.or`.
```roc
expect (Bool.or Bool.false Bool.true) == Bool.true
expect (Bool.true || Bool.true) == Bool.true
expect (Bool.false || Bool.true) == Bool.true
expect (Bool.true || Bool.false) == Bool.true
expect (Bool.false || Bool.false) == Bool.false
```

## Performance Details

In Roc the `&&` and `||` work the same way as any
other functions. However, in some languages `&&` and `||` are special-cased.
Refer to the note in `Bool.and` for more detail.

#### not

**Type Annotation**

```roc
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
```

#### isNotEq

**Type Annotation**

```roc
a, a -> Bool
    where a implements Eq
```

**Description**

This will call the function `Bool.isEq` 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.isNotEq`.

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

### Result

#### Result

**Type Annotation**

```roc

    [
        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.

#### isOk

**Type Annotation**

```roc
Result ok err -> Bool
```

**Description**

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

#### isErr

**Type Annotation**

```roc
Result ok err -> Bool
```

**Description**

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

#### withDefault

**Type Annotation**

```roc
Result ok err, ok -> ok
```

**Description**

If the result is `Ok`, returns the value it holds. Otherwise, returns
the given default value.
```roc
Result.withDefault (Ok 7) 42
Result.withDefault (Err "uh oh") 42
```

#### map

**Type Annotation**

```roc
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 [mapErr] to transform an `Err`.
```roc
Result.map (Ok 12) Num.neg
Result.map (Err "yipes!") Num.neg
```

Functions like `map` are common in Roc; see for example [List.map],
`Set.map`, and `Dict.map`.

#### mapErr

**Type Annotation**

```roc
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] to transform an `Ok`.
```roc
Result.mapErr (Err "yipes!") Str.isEmpty
Result.mapErr (Ok 12) Str.isEmpty
```

#### mapBoth

**Type Annotation**

```roc

    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

**Type Annotation**

```roc

    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

**Type Annotation**

```roc
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. Use `onErr` to transform an `Err`.
```roc
Result.try (Ok -1) \num -> if num < 0 then Err "negative!" else Ok -num
Result.try (Err "yipes!") \num -> if num < 0 then Err "negative!" else Ok -num
```

#### onErr

**Type Annotation**

```roc
Result a err, (err -> Result a otherErr) -> Result a otherErr
```

**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 `try` to transform an `Ok`.
```roc
Result.onErr (Ok 10) \errorNum -> Str.toU64 errorNum
Result.onErr (Err "42") \errorNum -> Str.toU64 errorNum
```

#### onErr!

**Type Annotation**

```roc
Result a err, (err => Result a otherErr) => Result a otherErr
```

**Description**

Like [onErr], but it allows the transformation function to produce effects.

```roc
Result.onErr (Err "missing user") \msg ->
    try Stdout.line! "ERROR: $(msg)"
    Err msg
```

### List

#### isEmpty

**Type Annotation**

```roc
List * -> Bool
```

**Description**

 Check if the list is empty.
```roc
List.isEmpty [1, 2, 3]

List.isEmpty []
```

#### get

**Type Annotation**

```roc
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

**Type Annotation**

```roc

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

#### set

**Type Annotation**

```roc

    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.dropAt].

#### update

**Type Annotation**

```roc

    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

**Type Annotation**

```roc
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
```

#### appendIfOk

**Type Annotation**

```roc
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.appendIfOk [1, 2, 3] (Ok 4)

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

#### prepend

**Type Annotation**

```roc
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
```

#### prependIfOk

**Type Annotation**

```roc
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

**Type Annotation**

```roc
List * -> U64
```

**Description**

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

One [List] can store up to `Num.maxI64` elements on 64-bit targets and `Num.maxI32` 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.

#### withCapacity

**Type Annotation**

```roc
U64 -> List *
```

**Description**

Create a list with space for at least capacity elements

#### reserve

**Type Annotation**

```roc
List a, U64 -> List a
```

**Description**

Enlarge the list for at least capacity additional elements

#### releaseExcessCapacity

**Type Annotation**

```roc
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

**Type Annotation**

```roc
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

**Type Annotation**

```roc
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

**Type Annotation**

```roc
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

**Type Annotation**

```roc
a, U64 -> List a
```

**Description**

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

#### reverse

**Type Annotation**

```roc
List a -> List a
```

**Description**

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

#### join

**Type Annotation**

```roc
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

**Type Annotation**

```roc
List a, a -> Bool
    where a implements Eq
```

#### walk

**Type Annotation**

```roc

    List elem, 
    state, 
    (state, elem -> state)
    -> state
```

**Description**

Build a value using each element in the list.

Starting with a given `state` value, this walks through each element in the
list from first to last, running a given `step` function on that element
which updates the `state`. It returns the final `state` at the end.

You can use it in a pipeline:
```roc
[2, 4, 8]
    |> List.walk 0 Num.add
```
This returns 14 because:
* `state` starts at 0
* Each `step` runs `Num.add state elem`, and the return value becomes the new `state`.

Here is a table of how `state` changes as [List.walk] walks over the elements
`[2, 4, 8]` using [Num.add] as its `step` function to determine the next `state`.

state | elem  | Num.add state elem
:---: | :---: | :----------------:
0     |       |
0     | 2     | 2
2     | 4     | 6
6     | 8     | 14

The following returns -6:
```roc
[1, 2, 3]
    |> List.walk 0 Num.sub
```
Note that in other languages, `walk` is sometimes called `reduce`,
`fold`, `foldLeft`, or `foldl`.

#### walkWithIndex

**Type Annotation**

```roc

    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.

#### walkWithIndexUntil

**Type Annotation**

```roc

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

**Description**

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

#### walkBackwards

**Type Annotation**

```roc

    List elem, 
    state, 
    (state, elem -> state)
    -> state
```

**Description**

Note that in other languages, `walkBackwards` is sometimes called `reduceRight`,
`fold`, `foldRight`, or `foldr`.

#### walkUntil

**Type Annotation**

```roc

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

**Description**

Same as [List.walk], except you can stop walking early.

## Performance Details

Compared to [List.walk], this can potentially visit fewer elements (which can
improve performance) at the cost of making each step take longer.
However, the added cost to each step is extremely small, and can easily
be outweighed if it results in skipping even a small number of elements.

As such, it is typically better for performance to use this over [List.walk]
if returning `Break` earlier than the last element is expected to be common.

#### walkBackwardsUntil

**Type Annotation**

```roc

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

**Description**

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

#### walkFrom

**Type Annotation**

```roc

    List elem, 
    U64, 
    state, 
    (state, elem -> state)
    -> state
```

**Description**

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

#### walkFromUntil

**Type Annotation**

```roc

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

**Description**

A combination of [List.walkFrom] and [List.walkUntil]

#### sum

**Type Annotation**

```roc
List (Num a) -> Num a
```

#### product

**Type Annotation**

```roc
List (Num a) -> Num a
```

#### any

**Type Annotation**

```roc
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

**Type Annotation**

```roc
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.

#### keepIf

**Type Annotation**

```roc
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.true`.
```roc
List.keepIf [1, 2, 3, 4] (\num -> num > 2)
```
## Performance Details

[List.keepIf] always returns a list that takes up exactly the same amount
of memory as the original, even if its length decreases. This is because it
can't know in advance exactly how much space it will need, and if it guesses a
length that's too low, it would have to re-allocate.

(If you want to do an operation like this which reduces the memory footprint
of the resulting list, you can do two passes over the list with [List.walk] - one
to calculate the precise new size, and another to populate the new list.)

If given a unique list, [List.keepIf] will mutate it in place to assemble the appropriate list.
If that happens, this function will not allocate any new memory on the heap.
If all elements in the list end up being kept, Roc will return the original
list unaltered.


#### dropIf

**Type Annotation**

```roc
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.dropIf [1, 2, 3, 4] (\num -> num > 2)
```
## Performance Details

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

#### countIf

**Type Annotation**

```roc
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.countIf [1, -2, -3] Num.isNegative == 2
expect List.countIf [1, 2, 3] (\num -> num > 1 ) == 2
```

#### keepOks

**Type Annotation**

```roc
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.keepOks ["1", "Two", "23", "Bird"] Str.toI32 == [1, 23]

expect List.keepOks [["a", "b"], [], ["c", "d", "e"], [] ] List.first == ["a", "c"]

fn = \str -> if Str.isEmpty str then Err StrWasEmpty else Ok str
expect List.keepOks ["", "a", "bc", "", "d", "ef", ""] fn == ["a", "bc", "d", "ef"]
```

#### keepErrs

**Type Annotation**

```roc
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.keepErrs [["a", "b"], [], [], ["c", "d", "e"]] List.last

fn = \str -> if Str.isEmpty str then Err StrWasEmpty else Ok (Str.len str)

List.keepErrs ["", "a", "bc", "", "d", "ef", ""]
```

#### map

**Type Annotation**

```roc
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.isEmpty == [Bool.true, Bool.false, Bool.false]
```

#### map2

**Type Annotation**

```roc

    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

**Type Annotation**

```roc

    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

**Type Annotation**

```roc

    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.

#### mapWithIndex

**Type Annotation**

```roc
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.mapWithIndex [10, 20, 30] (\num, index -> num + index) == [10, 21, 32]
```

#### range

**Type Annotation**

**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 } # returns [2, 3, 4, 5]
```
To exclude them, use `After` and `Before`, like so:
```roc
List.range { start: After 2, end: Before 5 } # returns [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 } # returns [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 } # returns [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 } # returns [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.

#### sortWith

**Type Annotation**

```roc

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

**Description**

Sort with a custom comparison function

#### sortAsc

**Type Annotation**

```roc
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.sortDesc] instead.

#### sortDesc

**Type Annotation**

```roc
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.sortAsc] instead.

#### swap

**Type Annotation**

```roc

    List a, 
    U64, 
    U64
    -> List a
```

#### first

**Type Annotation**

```roc
List a -> Result a [ListWasEmpty]
```

**Description**

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

#### takeFirst

**Type Annotation**

```roc
List elem, U64 -> List elem
```

**Description**

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

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

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


#### takeLast

**Type Annotation**

```roc
List elem, U64 -> List elem
```

**Description**

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

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

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


#### dropFirst

**Type Annotation**

```roc
List elem, U64 -> List elem
```

**Description**

Drops n elements from the beginning of the list.

#### dropLast

**Type Annotation**

```roc
List elem, U64 -> List elem
```

**Description**

Drops n elements from the end of the list.

#### dropAt

**Type Annotation**

```roc
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

**Type Annotation**

```roc
List (Num a) -> Result (Num a) [ListWasEmpty]
```

#### max

**Type Annotation**

```roc
List (Num a) -> Result (Num a) [ListWasEmpty]
```

#### joinMap

**Type Annotation**

```roc
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 `concatMap` in other languages.

#### findFirst

**Type Annotation**

```roc
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.

#### findLast

**Type Annotation**

```roc
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.

#### findFirstIndex

**Type Annotation**

```roc
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.

#### findLastIndex

**Type Annotation**

```roc
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

**Type Annotation**

```roc

    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.takeLast` can do that more efficiently.

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

#### intersperse

**Type Annotation**

```roc
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]
```

#### startsWith

**Type Annotation**

```roc
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.

#### endsWith

**Type Annotation**

```roc
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.

#### splitAt

**Type Annotation**

```roc

    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.)

#### splitOn

**Type Annotation**

```roc
List a, a -> List (List a)
    where a implements Eq
```

**Description**

Splits the input list on the delimiter element.

```roc
List.splitOn [1, 2, 3] 2 == [[1], [3]]
```

#### splitOnList

**Type Annotation**

```roc
List a, List a -> List (List a)
    where a implements Eq
```

**Description**

Splits the input list on the delimiter list.

```roc
List.splitOnList [1, 2, 3] [1, 2] == [[], [3]]
```

#### splitFirst

**Type Annotation**

```roc

    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.splitFirst [Foo, Z, Bar, Z, Baz] Z == Ok { before: [Foo], after: [Bar, Z, Baz] }
```

#### splitLast

**Type Annotation**

```roc

    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.splitLast [Foo, Z, Bar, Z, Baz] Z == Ok { before: [Foo, Z, Bar], after: [Baz] }
```

#### chunksOf

**Type Annotation**

```roc
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.

#### mapTry

**Type Annotation**

```roc
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`, [mapTry] immediately returns that `Err`.
If it returns `Ok` for every element, [mapTry] returns `Ok` with the transformed list.

#### walkTry

**Type Annotation**

```roc

    List elem, 
    state, 
    (state, elem -> Result state err)
    -> Result state err
```

**Description**

Same as [List.walk], except you can stop walking early by returning `Err`.

## Performance Details

Compared to [List.walk], this can potentially visit fewer elements (which can
improve performance) at the cost of making each step take longer.
However, the added cost to each step is extremely small, and can easily
be outweighed if it results in skipping even a small number of elements.

As such, it is typically better for performance to use this over [List.walk]
if returning `Break` earlier than the last element is expected to be common.

#### concatUtf8

**Type Annotation**

```roc
List U8, Str -> List U8
```

**Description**

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

#### forEach!

**Type Annotation**

```roc
List a, (a => {}) => {}
```

**Description**

Run an effectful function for each element on the list.

```roc
List.forEach! ["Alice", "Bob", "Charlie"] \name ->
    createAccount! name
    log! "Account created"
```

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

#### forEachTry!

**Type Annotation**

```roc
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.forEachTry! filesToDelete \path ->
    try File.delete! path
    Stdout.line! "$(path) deleted"
```

### Dict

#### Dict

**Type Annotation**

**Description**

A [dictionary](https://en.wikipedia.org/wiki/Associative_array) that lets you
associate keys with values.

## Inserting

The most basic way to use a dictionary is to start with an empty one and
then:
1. Call [Dict.insert] passing a key and a value, to associate that key with
that value in the dictionary.
2. Later, call [Dict.get] passing the same key as before, and it will return
the value you stored.

Here's an example of a dictionary which uses a city's name as the key, and
its population as the associated value.
```roc
populationByCity =
    Dict.empty {}
    |> Dict.insert "London" 8_961_989
    |> Dict.insert "Philadelphia" 1_603_797
    |> Dict.insert "Shanghai" 24_870_895
    |> Dict.insert "Delhi" 16_787_941
    |> Dict.insert "Amsterdam" 872_680
```
## Accessing keys or values

We can use [Dict.keys] and [Dict.values] functions to get only the keys or
only the values.

You may notice that these lists have the same order as the original insertion
order. This will be true if all you ever do is [Dict.insert] and [Dict.get] operations
on the dictionary, but [Dict.remove] operations can change this order.

## Removing

We can remove an element from the dictionary, like so:
```roc
populationByCity
    |> Dict.remove "Philadelphia"
    |> Dict.keys
    ==
    ["London", "Amsterdam", "Shanghai", "Delhi"]
```
Notice that the order has changed. Philadelphia was not only removed from the
list, but Amsterdam - the last entry we inserted - has been moved into the
spot where Philadelphia was previously. This is exactly what [Dict.remove]
does. It removes an element and moves the most recent insertion into the
vacated spot.

This move is done as a performance optimization, and it lets [remove] have
[constant time complexity](https://en.wikipedia.org/wiki/Time_complexity#Constant_time).

Dict is inspired by [IndexMap](https://docs.rs/indexmap/latest/indexmap/map/struct.IndexMap.html).
The internal implementation of a dictionary is almost identical to [ankerl::unordered_dense](https://github.com/martinus/unordered_dense).
It has a list of keys value pairs that is ordered based on insertion.
It uses a list of indices into the data as the backing of a hash map.

#### empty

**Type Annotation**

```roc
{} -> Dict * *
```

**Description**

Return an empty dictionary.
```roc
emptyDict = Dict.empty {}
```

#### withCapacity

**Type Annotation**

```roc
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

**Type Annotation**

```roc
Dict k v, U64 -> Dict k v
```

**Description**

Enlarge the dictionary for at least capacity additional elements

#### releaseExcessCapacity

**Type Annotation**

```roc
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

**Type Annotation**

```roc
Dict * * -> U64
```

**Description**

Returns the max number of elements the dictionary can hold before requiring a rehash.
```roc
foodDict =
    Dict.empty {}
    |> Dict.insert "apple" "fruit"

capacityOfDict = Dict.capacity foodDict
```

#### single

**Type Annotation**

```roc
k, v -> Dict k v
```

**Description**

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

#### fromList

**Type Annotation**

```roc
    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.isEq (Dict.fromList [(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

**Type Annotation**

```roc
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.isEq 3
```

#### isEmpty

**Type Annotation**

```roc
Dict * * -> Bool
```

**Description**

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

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

#### clear

**Type Annotation**

```roc
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"

clearSongs = Dict.clear songs

expect Dict.len clearSongs == 0
```

#### map

**Type Annotation**

```roc
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.

#### joinMap

**Type Annotation**

```roc
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.insertAll]) into one dictionary.

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

#### walk

**Type Annotation**

```roc

    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.isEq 36
```

#### walkUntil

**Type Annotation**

```roc

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

**Description**

Same as [Dict.walk], except you can stop walking early.

## Performance Details

Compared to [Dict.walk], this can potentially visit fewer elements (which can
improve performance) at the cost of making each step take longer.
However, the added cost to each step is extremely small, and can easily
be outweighed if it results in skipping even a small number of elements.

As such, it is typically better for performance to use this over [Dict.walk]
if returning `Break` earlier than the last element is expected to be common.
```roc
people =
    Dict.empty {}
    |> Dict.insert "Alice" 17
    |> Dict.insert "Bob" 18
    |> Dict.insert "Charlie" 19

isAdult = \_, _, age ->
        if age >= 18 then
            Break Bool.true
        else
            Continue Bool.false

someoneIsAnAdult = Dict.walkUntil people Bool.false isAdult

expect someoneIsAnAdult == Bool.true
```

#### keepIf

**Type Annotation**

```roc

    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.keepIf \(_k, v) -> v >= 18
    |> Dict.len
    |> Bool.isEq 2
```

#### dropIf

**Type Annotation**

```roc

    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.dropIf \(_k, v) -> v >= 18
    |> Dict.len
    |> Bool.isEq 1
```

#### get

**Type Annotation**

```roc
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 "Apple"
    |> Dict.insert 2 "Orange"

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

#### contains

**Type Annotation**

```roc
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.isEq Bool.true
```

#### insert

**Type Annotation**

```roc

    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.isEq (Ok 12)
```

#### remove

**Type Annotation**

```roc
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.isEq 0
```

#### update

**Type Annotation**

```roc

    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
alterValue : Result Bool [Missing] -> Result Bool [Missing]
alterValue = \possibleValue ->
    when possibleValue is
        Err Missing -> Ok Bool.false
        Ok value -> if value then Err Missing else Ok Bool.true

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

#### toList

**Type Annotation**

```roc

    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.toList] or [Dict.walk] instead.
```roc
expect
    Dict.single 1 "One"
    |> Dict.insert 2 "Two"
    |> Dict.insert 3 "Three"
    |> Dict.insert 4 "Four"
    |> Dict.toList
    |> Bool.isEq [(1, "One"), (2, "Two"), (3, "Three"), (4, "Four")]
```

#### keys

**Type Annotation**

```roc
Dict k v -> List k
```

**Description**

Returns the keys of a dictionary as a [List].
This requires allocating a temporary [List], prefer using [Dict.toList] 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.isEq [1,2,3,4]
```

#### values

**Type Annotation**

```roc
Dict k v -> List v
```

**Description**

Returns the values of a dictionary as a [List].
This requires allocating a temporary [List], prefer using [Dict.toList] 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.isEq ["One","Two","Three","Four"]
```

#### insertAll

**Type Annotation**

```roc
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.insertAll first second == expected
```

#### keepShared

**Type Annotation**

```roc
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.keepShared first second == expected
```

#### removeAll

**Type Annotation**

```roc
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.removeAll first second == expected
```

### Set

#### Set

**Type Annotation**

**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

**Type Annotation**

```roc
{} -> Set *
```

**Description**

Creates a new empty `Set`.
```roc
emptySet = Set.empty {}
countValues = Set.len emptySet

expect countValues == 0
```

#### withCapacity

**Type Annotation**

```roc
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

**Type Annotation**

```roc
Set k, U64 -> Set k
```

**Description**

Enlarge the set for at least capacity additional elements

#### releaseExcessCapacity

**Type Annotation**

```roc
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

**Type Annotation**

```roc
k -> Set k
```

**Description**

Creates a new `Set` with a single value.
```roc
singleItemSet = Set.single "Apple"
countValues = Set.len singleItemSet

expect countValues == 1
```

#### insert

**Type Annotation**

```roc
Set k, k -> Set k
```

**Description**

Insert a value into a `Set`.
```roc
fewItemSet =
    Set.empty {}
    |> Set.insert "Apple"
    |> Set.insert "Pear"
    |> Set.insert "Banana"

countValues = Set.len fewItemSet

expect countValues == 3
```

#### len

**Type Annotation**

```roc
Set * -> U64
```

**Description**

Counts the number of values in a given `Set`.
```roc
fewItemSet =
    Set.empty {}
    |> Set.insert "Apple"
    |> Set.insert "Pear"
    |> Set.insert "Banana"

countValues = Set.len fewItemSet

expect countValues == 3
```

#### capacity

**Type Annotation**

```roc
Set * -> U64
```

**Description**

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

capacityOfSet = Set.capacity foodSet
```

#### isEmpty

**Type Annotation**

```roc
Set * -> Bool
```

**Description**

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

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

#### remove

**Type Annotation**

```roc
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

**Type Annotation**

```roc
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

hasApple = Set.contains fruit Apple
hasBanana = Set.contains fruit Banana

expect hasApple == Bool.true
expect hasBanana == Bool.false
```

#### toList

**Type Annotation**

```roc
Set k -> List k
```

**Description**

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

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

expect Set.toList numbers == values
```

#### fromList

**Type Annotation**

```roc
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.fromList [Pear, Apple, Banana] == values
```

#### union

**Type Annotation**

```roc
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.fromList [Left, Right]
```

#### intersection

**Type Annotation**

```roc
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.fromList [Left, Other]
set2 = Set.fromList [Left, Right]

expect Set.intersection set1 set2 == Set.single Left
```

#### difference

**Type Annotation**

```roc
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.fromList [Left, Right, Up, Down]
second = Set.fromList [Left, Right]

expect Set.difference first second == Set.fromList [Up, Down]
```

#### walk

**Type Annotation**

```roc

    Set k, 
    state, 
    (state, k -> state)
    -> state
```

**Description**

Iterate through the values of a given `Set` and build a value.
```roc
values = Set.fromList ["March", "April", "May"]

startsWithLetterM = \month ->
    when Str.toUtf8 month is
        ['M', ..] -> Bool.true
        _ -> Bool.false

reduce = \state, k ->
    if startsWithLetterM k then
        state + 1
    else
        state

result = Set.walk values 0 reduce

expect result == 2
```

#### map

**Type Annotation**

```roc
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.

#### joinMap

**Type Annotation**

```roc
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 `concatMap` in other languages.

#### walkUntil

**Type Annotation**

```roc

    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.fromList [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.walkUntil numbers NotFound find42

expect result == FoundTheAnswer
```

#### keepIf

**Type Annotation**

```roc
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.fromList [1,2,3,4,5]
    |> Set.keepIf \k -> k >= 3
    |> Bool.isEq (Set.fromList [3,4,5])
```

#### dropIf

**Type Annotation**

```roc
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.fromList [1,2,3,4,5]
    |> Set.dropIf \k -> k >= 3
    |> Bool.isEq (Set.fromList [1,2])
```

### Decode

#### DecodeError

**Type Annotation**

```roc
[TooShort]
```

**Description**

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

#### DecodeResult

**Type Annotation**

**Description**

Return type of a [Decoder].

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

    actual.result == expected
```

#### Decoder

**Type Annotation**

**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

**Type Annotation**

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

**Description**

Definition of the [Decoding] ability

#### DecoderFormatting

**Type Annotation**

```roc
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

**Type Annotation**

```roc
(List U8, fmt -> DecodeResult val) -> Decoder val fmt
    where fmt implements DecoderFormatting
```

**Description**

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

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

#### decodeWith

**Type Annotation**

```roc

    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

#### fromBytesPartial

**Type Annotation**

```roc
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.toUtf8
    actual = Decode.fromBytesPartial input Json.json
    expected = Ok "hello"

    actual.result == expected
```

#### fromBytes

**Type Annotation**

```roc
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.toUtf8
    actual = Decode.fromBytes input Json.json
    expected = Ok "hello"

    actual == expected
```

#### mapResult

**Type Annotation**

```roc
DecodeResult a, (a -> b) -> DecodeResult b
```

**Description**

Transform the `val` of a [DecodeResult]

### Encode

#### Encoder

**Type Annotation**

#### Encoding

**Type Annotation**

```roc
implements
    toEncoder : val -> Encoder fmt
        where val implements Encoding, fmt implements EncoderFormatting
```

#### EncoderFormatting

**Type Annotation**

```roc
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

**Type Annotation**

```roc
(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
    customEncoder = Encode.custom (\bytes, _fmt -> List.append bytes 42)

    actual = Encode.appendWith [] customEncoder Core.json
    expected = [42] # Expected result is a list with a single byte, 42

    actual == expected
```

#### appendWith

**Type Annotation**

```roc

    List U8, 
    Encoder fmt, 
    fmt
    -> List U8
    where fmt implements EncoderFormatting
```

#### append

**Type Annotation**

```roc

    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.toUtf8 """{"foo":43}"""

    actual == expected
```

#### toBytes

**Type Annotation**

```roc
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
    fooRec = { foo: 42 }

    actual = Encode.toBytes fooRec Core.json
    expected = Str.toUtf8 """{"foo":42}"""

    actual == expected
```

### Hash

#### Hash

**Type Annotation**

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

**Description**

A value that can be hashed.

#### Hasher

**Type Annotation**

```roc
implements
    addBytes : a, List U8 -> a
        where a implements Hasher
    addU8 : a, U8 -> a
        where a implements Hasher
    addU16 : a, U16 -> a
        where a implements Hasher
    addU32 : a, U32 -> a
        where a implements Hasher
    addU64 : a, U64 -> a
        where a implements Hasher
    addU128 : 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.

#### hashStrBytes

**Type Annotation**

**Description**

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

#### hashList

**Type Annotation**

**Description**

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

#### hashBool

**Type Annotation**

```roc
a, Bool -> a
    where a implements Hasher
```

**Description**

Adds a single [Bool] to a hasher.

#### hashI8

**Type Annotation**

```roc
a, I8 -> a
    where a implements Hasher
```

**Description**

Adds a single I8 to a hasher.

#### hashI16

**Type Annotation**

```roc
a, I16 -> a
    where a implements Hasher
```

**Description**

Adds a single I16 to a hasher.

#### hashI32

**Type Annotation**

```roc
a, I32 -> a
    where a implements Hasher
```

**Description**

Adds a single I32 to a hasher.

#### hashI64

**Type Annotation**

```roc
a, I64 -> a
    where a implements Hasher
```

**Description**

Adds a single I64 to a hasher.

#### hashI128

**Type Annotation**

```roc
a, I128 -> a
    where a implements Hasher
```

**Description**

Adds a single I128 to a hasher.

#### hashDec

**Type Annotation**

```roc
a, Dec -> a
    where a implements Hasher
```

**Description**

Adds a single [Dec] to a hasher.

#### hashUnordered

**Type Annotation**

**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

**Type Annotation**

```roc
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

**Type Annotation**

```roc
Box a -> a
```

**Description**

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

### Inspect

#### KeyValWalker

**Type Annotation**

```roc

    collection, 
    state,     
    (state, 
    key, 
    val
    -> state)
    -> state
```

#### ElemWalker

**Type Annotation**

```roc

    collection, 
    state, 
    (state, elem -> state)
    -> state
```

#### InspectFormatter

**Type Annotation**

```roc
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
```

#### Inspector

**Type Annotation**

#### custom

**Type Annotation**

```roc
(f -> f) -> Inspector f
    where f implements InspectFormatter
```

#### apply

**Type Annotation**

```roc
Inspector f, f -> f
    where f implements InspectFormatter
```

#### Inspect

**Type Annotation**

```roc
implements
    toInspector : val -> Inspector f
        where val implements Inspect, f implements InspectFormatter
```

#### inspect

**Type Annotation**

```roc
val -> f
    where val implements Inspect, f implements InspectFormatter
```

#### toStr

**Type Annotation**

```roc
val -> Str
    where val implements Inspect
```

### Task

#### Task

**Type Annotation**

**Description**

A Task represents an effect; an interaction with state outside your Roc
program, such as the terminal's standard output, or a file.

#### forever

**Type Annotation**

```roc
Task a err -> Task * err
```

**Description**

Run a task repeatedly, until it fails with `err`. Note that this task does not return a success value.

#### loop

**Type Annotation**

```roc

    state,     
    (state
    -> Task 
        [
            Step state,
            Done done
        ] err)
    -> Task done err
```

**Description**

Run a task repeatedly, until it fails with `err` or completes with `done`.

```
sum =
    Task.loop! 0 \total ->
        numResult =
            Stdin.line
                |> Task.result!
                |> Result.try Str.toU64

        when numResult is
            Ok num -> Task.ok (Step (total + num))
            Err (StdinErr EndOfFile) -> Task.ok (Done total)
            Err InvalidNumStr -> Task.err NonNumberGiven
```

#### ok

**Type Annotation**

```roc
a -> Task a *
```

**Description**

Create a task that always succeeds with the value provided.

```
# Always succeeds with "Louis"
getName : Task.Task Str *
getName = Task.ok "Louis"
```


#### err

**Type Annotation**

```roc
a -> Task * a
```

**Description**

Create a task that always fails with the error provided.

```
# Always fails with the tag `CustomError Str`
customError : Str -> Task.Task {} [CustomError Str]
customError = \err -> Task.err (CustomError err)
```


#### attempt

**Type Annotation**

```roc
Task a b, (Result a b -> Task c d) -> Task c d
```

**Description**

Transform a given Task with a function that handles the success or error case
and returns another task based on that. This is useful for chaining tasks
together or performing error handling and recovery.

Consider the following task:

`canFail : Task {} [Failure, AnotherFail, YetAnotherFail]`

We can use [attempt] to handle the failure cases using the following:

```
Task.attempt canFail \result ->
    when result is
        Ok Success -> Stdout.line "Success!"
        Err Failure -> Stdout.line "Oops, failed!"
        Err AnotherFail -> Stdout.line "Ooooops, another failure!"
        Err YetAnotherFail -> Stdout.line "Really big oooooops, yet again!"
```

Here we know that the `canFail` task may fail, and so we use
`Task.attempt` to convert the task to a `Result` and then use pattern
matching to handle the success and possible failure cases.

#### await

**Type Annotation**

```roc
Task a b, (a -> Task c b) -> Task c b
```

**Description**

Take the success value from a given [Task] and use that to generate a new [Task].

We can [await] Task results with callbacks:

```
Task.await (Stdin.line "What's your name?") \name ->
    Stdout.line "Your name is: $(name)"
```

Or we can more succinctly use the `!` bang operator, which desugars to [await]:

```
name = Stdin.line! "What's your name?"
Stdout.line "Your name is: $(name)"
```

#### onErr

**Type Annotation**

```roc
Task a b, (b -> Task a c) -> Task a c
```

**Description**

Take the error value from a given [Task] and use that to generate a new [Task].

```
# Prints "Something went wrong!" to standard error if `canFail` fails.
canFail
|> Task.onErr \_ -> Stderr.line "Something went wrong!"
```

#### map

**Type Annotation**

```roc
Task a c, (a -> b) -> Task b c
```

**Description**

Transform the success value of a given [Task] with a given function.

```
# Succeeds with a value of "Bonjour Louis!"
Task.ok "Louis"
|> Task.map (\name -> "Bonjour $(name)!")
```

#### mapErr

**Type Annotation**

```roc
Task c a, (a -> b) -> Task c b
```

**Description**

Transform the error value of a given [Task] with a given function.

```
# Ignore the fail value, and map it to the tag `CustomError`
canFail
|> Task.mapErr \_ -> CustomError
```

#### fromResult

**Type Annotation**

```roc
Result a b -> Task a b
```

**Description**

Use a Result among other Tasks by converting it into a [Task].

#### batch

**Type Annotation**

```roc
Task a c -> Task (a -> b) c -> Task b c
```

**Description**

Apply a task to another task applicatively. This can be used with
[ok] to build a [Task] that returns a record.

The following example returns a Record with two fields, `apples` and
`oranges`, each of which is a `List Str`. If it fails it returns the tag
`NoFruitAvailable`.

```
getFruitBasket : Task { apples : List Str, oranges : List Str } [NoFruitAvailable]
getFruitBasket = Task.ok {
    apples: <- getFruit Apples |> Task.batch,
    oranges: <- getFruit Oranges |> Task.batch,
}
```

#### sequence

**Type Annotation**

```roc
List (Task ok err) -> Task (List ok) err
```

**Description**

Apply each task in a list sequentially, and return a list of the resulting values.
Each task will be awaited before beginning the next task.

```
fetchAuthorTasks : List (Task Author [DbError])

getAuthors : Task (List Author) [DbError]
getAuthors = Task.sequence fetchAuthorTasks
```


#### forEach

**Type Annotation**

```roc
List a, (a -> Task {} b) -> Task {} b
```

**Description**

Apply a task repeatedly for each item in a list

```
authors : List Author
saveAuthor : Author -> Task {} [DbError]

saveAuthors : Task (List Author) [DbError]
saveAuthors = Task.forEach authors saveAuthor
```


#### result

**Type Annotation**

```roc
Task ok err -> Task (Result ok err) *
```

**Description**

Transform a task that can either succeed with `ok`, or fail with `err`, into
a task that succeeds with `Result ok err`.

This is useful when chaining tasks using the `!` suffix. For example:

```
# Path.roc
checkFile : Str -> Task [Good, Bad] [IOError]

# main.roc
when checkFile "/usr/local/bin/roc" |> Task.result! is
    Ok Good -> "..."
    Ok Bad -> "..."
    Err IOError -> "..."
```


