1## Full Docs per Module
2### Str
3
4Utf8Problem : [ InvalidStartByte, UnexpectedEndOfSequence, ExpectedContinuation, OverlongEncoding, CodepointTooLarge, EncodesSurrogateHalf ]
5
6is_empty : Str -> Bool
7
8Description:
9Returns [Bool.true] if the string is empty, and [Bool.false] otherwise.
10```roc
11expect Str.is_empty("hi!") == Bool.false
12expect Str.is_empty("") == Bool.true
13```
14
15concat : Str, Str -> Str
16
17Description:
18Concatenates two strings together.
19```roc
20expect Str.concat("ab", "cd") == "abcd"
21expect Str.concat("hello", "") == "hello"
22expect Str.concat("", "") == ""
23```
24
25with_capacity : U64 -> Str
26
27Description:
28Returns an empty string with the specified capacity pre-allocated. Use when building strings incrementally with [Str.concat] to avoid reallocations. Prefer over `""` when concatenating. See [Str.reserve] for existing strings.
29```roc
30Str.with_capacity(45) |> Str.concat("Hello") |> Str.concat(", World!")
31```
32
33reserve : Str, U64 -> Str
34
35Description:
36Increases a string's capacity by at least the given number of additional bytes, preventing reallocations during subsequent [Str.concat] calls. For empty strings, use [Str.with_capacity] instead.
37```roc
38greeting |> Str.reserve(21) |> Str.concat(", ") |> Str.concat(subject) |> Str.concat("!")
39```
40
41join_with : List Str, Str -> Str
42
43Description:
44Combines a [List] of strings into a single string, with a separator
45string in between each.
46```roc
47expect Str.join_with(["one", "two", "three"], ", ") == "one, two, three"
48expect Str.join_with(["1", "2", "3", "4"], ".") == "1.2.3.4"
49```
50
51split_on : Str, Str -> List Str
52
53Description:
54Split a string around a separator.
55
56Passing `""` for the separator is not useful;
57it returns the original string wrapped in a [List].
58```roc
59expect Str.split_on("1,2,3", ",") == ["1","2","3"]
60expect Str.split_on("1,2,3", "") == ["1,2,3"]
61```
62
63repeat : Str, U64 -> Str
64
65Description:
66Repeats a string the given number of times.
67```roc
68expect Str.repeat("z", 3) == "zzz"
69expect Str.repeat("na", 8) == "nananananananana"
70```
71Returns `""` when given `""` for the string or `0` for the count.
72```roc
73expect Str.repeat("", 10) == ""
74expect Str.repeat("anything", 0) == ""
75```
76
77len : Str -> [LearnAboutStringsInRoc Str]
78
79Description:
80A stub function to help people discover [how they should handle this in Roc](https://www.roc-lang.org/faq.html#strings-in-roc).
81
82to_utf8 : Str -> List U8
83
84Description:
85Returns a [List] of the string's [U8] UTF-8 [code units](https://unicode.org/glossary/#code_unit).
86(To split the string into a [List] of smaller [Str] values instead of [U8] values,
87see [Str.split_on].)
88```roc
89expect Str.to_utf8("Roc") == [82, 111, 99]
90expect Str.to_utf8("鹏") == [233, 185, 143]
91expect Str.to_utf8("சி") == [224, 174, 154, 224, 174, 191]
92expect Str.to_utf8("🐦") == [240, 159, 144, 166]
93```
94
95from_utf8 : List U8 -> Result Str [ BadUtf8 { problem : Utf8Problem, index : U64 } ]
96
97Description:
98Converts a [List] of [U8] UTF-8 [code units](https://unicode.org/glossary/#code_unit) to a string.
99
100Returns `Err` if the given bytes are invalid UTF-8, and returns `Ok ""` when given `[]`.
101```roc
102expect Str.from_utf8([82, 111, 99]) == Ok("Roc")
103expect Str.from_utf8([233, 185, 143]) == Ok("鹏")
104expect Str.from_utf8([224, 174, 154, 224, 174, 191]) == Ok("சி")
105expect Str.from_utf8([240, 159, 144, 166]) == Ok("🐦")
106expect Str.from_utf8([]) == Ok("")
107expect Str.from_utf8([255]) |> Result.is_err
108```
109
110from_utf8_lossy : List U8 -> Str
111
112Description:
113Converts a [List] of [U8] UTF-8 [code units](https://unicode.org/glossary/#code_unit) to a string.
114Any grouping of invalid byte sequences are replaced with a single unicode replacement character '�'.
115
116An invalid byte sequence is defined as
117- a 2-byte-sequence starting byte, followed by less than 1 continuation byte
118- a 3-byte-sequence starting byte, followed by less than 2 continuation bytes
119- a 4-byte-sequence starting byte, followed by less than 3 continuation bytes
120- an invalid codepoint from the surrogate pair block
121- an invalid codepoint greater than 0x110000 encoded as a 4-byte sequence
122- any valid codepoint encoded as an incorrect sequence, for instance a codepoint that should be a 2-byte sequence encoded as a 3- or 4-byte sequence
123
124```roc
125expect (Str.from_utf8_lossy [82, 111, 99, 240, 159, 144, 166]) == "Roc🐦"
126expect (Str.from_utf8_lossy [82, 255, 99]) == "R�c"
127expect (Str.from_utf8_lossy [82, 0xED, 0xA0, 0xBD, 99]) == "R�c"
128```
129
130from_utf16 : List U16 -> Result Str [ BadUtf16 { problem : Utf8Problem, index : U64 } ]
131
132Description:
133Converts a [List] of [U16] UTF-16 (little-endian) [code units](https://unicode.org/glossary/#code_unit) to a string.
134
135```roc
136expect Str.from_utf16([82, 111, 99]) == Ok("Roc")
137expect Str.from_utf16([0xb9a, 0xbbf]) == Ok("சி")
138expect Str.from_utf16([0xd83d, 0xdc26]) == Ok("🐦")
139expect Str.from_utf16([]) == Ok("")
140# unpaired surrogates, first and second halves
141expect Str.from_utf16([82, 0xd83d, 99]) |> Result.is_err
142expect Str.from_utf16([82, 0xdc96, 99]) |> Result.is_err
143```
144
145from_utf16_lossy : List U16 -> Str
146
147Description:
148Converts a [List] of [U16] UTF-16 (little-endian) [code units](https://unicode.org/glossary/#code_unit) to a string.
149Any unpaired surrogate code unit is replaced with a single unicode replacement character '�'.
150
151```roc
152expect Str.from_utf16_lossy([82, 111, 99, 0xd83d, 0xdc26]) == "Roc🐦"
153expect Str.from_utf16_lossy([82, 0xdc96, 99]) == "R�c"
154```
155
156from_utf32 : List U32 -> Result Str [ BadUtf32 { problem : Utf8Problem, index : U64 } ]
157
158from_utf32_lossy : List U32 -> Str
159
160Description:
161Converts a [List] of [U32] UTF-32 [code units](https://unicode.org/glossary/#code_unit) to a string.
162Any invalid code points are replaced with a single unicode replacement character '�'.
163```roc
164expect Str.from_utf32_lossy([82, 111, 99, 0x1f426]) == "Roc🐦"
165expect Str.from_utf32_lossy([82, 0x110000, 99]) == "R�c"
166```
167
168starts_with : Str, Str -> Bool
169
170Description:
171Check if the given [Str] starts with a value.
172```roc
173expect Str.starts_with("ABC", "A") == Bool.true
174expect Str.starts_with("ABC", "X") == Bool.false
175```
176
177ends_with : Str, Str -> Bool
178
179Description:
180Check if the given [Str] ends with a value.
181```roc
182expect Str.ends_with("ABC", "C") == Bool.true
183expect Str.ends_with("ABC", "X") == Bool.false
184```
185
186trim : Str -> Str
187
188Description:
189Return the [Str] with all whitespace removed from both the beginning
190as well as the end.
191```roc
192expect Str.trim(" Hello \n\n") == "Hello"
193```
194
195trim_start : Str -> Str
196
197Description:
198Return the [Str] with all whitespace removed from the beginning.
199```roc
200expect Str.trim_start(" Hello \n\n") == "Hello \n\n"
201```
202
203trim_end : Str -> Str
204
205Description:
206Return the [Str] with all whitespace removed from the end.
207```roc
208expect Str.trim_end(" Hello \n\n") == " Hello"
209```
210
211to_dec : Str -> Result Dec [InvalidNumStr]
212
213Description:
214Encode a [Str] to a [Dec]. A [Dec] value is a 128-bit decimal
215[fixed-point number](https://en.wikipedia.org/wiki/Fixed-point_arithmetic).
216```roc
217expect Str.to_dec("10") == Ok(10dec)
218expect Str.to_dec("-0.25") == Ok(-0.25dec)
219expect Str.to_dec("not a number") == Err(InvalidNumStr)
220```
221
222to_f64 : Str -> Result F64 [InvalidNumStr]
223
224Description:
225Encode a [Str] to a [F64]. A [F64] value is a 64-bit
226[floating-point number](https://en.wikipedia.org/wiki/IEEE_754) and can be
227specified with a `f64` suffix.
228```roc
229expect Str.to_f64("0.10") == Ok(0.10f64)
230expect Str.to_f64("not a number") == Err(InvalidNumStr)
231```
232
233to_f32 : Str -> Result F32 [InvalidNumStr]
234
235Description:
236Encode a [Str] to a [F32].A [F32] value is a 32-bit
237[floating-point number](https://en.wikipedia.org/wiki/IEEE_754) and can be
238specified with a `f32` suffix.
239```roc
240expect Str.to_f32("0.10") == Ok(0.10f32)
241expect Str.to_f32("not a number") == Err(InvalidNumStr)
242```
243
244to_u128 : Str -> Result U128 [InvalidNumStr]
245
246Description:
247Encode a [Str] to an unsigned [U128] integer. A [U128] value can hold numbers
248from `0` to `340_282_366_920_938_463_463_374_607_431_768_211_455` (over
249340 undecillion). It can be specified with a u128 suffix.
250```roc
251expect Str.to_u128("1500") == Ok(1500u128)
252expect Str.to_u128("0.1") == Err(InvalidNumStr)
253expect Str.to_u128("-1") == Err(InvalidNumStr)
254expect Str.to_u128("not a number") == Err(InvalidNumStr)
255```
256
257to_i128 : Str -> Result I128 [InvalidNumStr]
258
259Description:
260Encode a [Str] to a signed [I128] integer. A [I128] value can hold numbers
261from `-170_141_183_460_469_231_731_687_303_715_884_105_728` to
262`170_141_183_460_469_231_731_687_303_715_884_105_727`. It can be specified
263with a i128 suffix.
264```roc
265expect Str.to_u128("1500") == Ok(1500i128)
266expect Str.to_i128("-1") == Ok(-1i128)
267expect Str.to_i128("0.1") == Err(InvalidNumStr)
268expect Str.to_i128("not a number") == Err(InvalidNumStr)
269```
270
271to_u64 : Str -> Result U64 [InvalidNumStr]
272
273Description:
274Encode a [Str] to an unsigned [U64] integer. A [U64] value can hold numbers
275from `0` to `18_446_744_073_709_551_615` (over 18 quintillion). It
276can be specified with a u64 suffix.
277```roc
278expect Str.to_u64("1500") == Ok(1500u64)
279expect Str.to_u64("0.1") == Err(InvalidNumStr)
280expect Str.to_u64("-1") == Err(InvalidNumStr)
281expect Str.to_u64("not a number") == Err(InvalidNumStr)
282```
283
284to_i64 : Str -> Result I64 [InvalidNumStr]
285
286Description:
287Encode a [Str] to a signed [I64] integer. A [I64] value can hold numbers
288from `-9_223_372_036_854_775_808` to `9_223_372_036_854_775_807`. It can be
289specified with a i64 suffix.
290```roc
291expect Str.to_i64("1500") == Ok(1500i64)
292expect Str.to_i64("-1") == Ok(-1i64)
293expect Str.to_i64("0.1") == Err(InvalidNumStr)
294expect Str.to_i64("not a number") == Err(InvalidNumStr)
295```
296
297to_u32 : Str -> Result U32 [InvalidNumStr]
298
299Description:
300Encode a [Str] to an unsigned [U32] integer. A [U32] value can hold numbers
301from `0` to `4_294_967_295` (over 4 billion). It can be specified with
302a u32 suffix.
303```roc
304expect Str.to_u32("1500") == Ok(1500u32)
305expect Str.to_u32("0.1") == Err(InvalidNumStr)
306expect Str.to_u32("-1") == Err(InvalidNumStr)
307expect Str.to_u32("not a number") == Err(InvalidNumStr)
308```
309
310to_i32 : Str -> Result I32 [InvalidNumStr]
311
312Description:
313Encode a [Str] to a signed [I32] integer. A [I32] value can hold numbers
314from `-2_147_483_648` to `2_147_483_647`. It can be
315specified with a i32 suffix.
316```roc
317expect Str.to_i32("1500") == Ok(1500i32)
318expect Str.to_i32("-1") == Ok(-1i32)
319expect Str.to_i32("0.1") == Err(InvalidNumStr)
320expect Str.to_i32("not a number") == Err(InvalidNumStr)
321```
322
323to_u16 : Str -> Result U16 [InvalidNumStr]
324
325Description:
326Encode a [Str] to an unsigned [U16] integer. A [U16] value can hold numbers
327from `0` to `65_535`. It can be specified with a u16 suffix.
328```roc
329expect Str.to_u16("1500") == Ok(1500u16)
330expect Str.to_u16("0.1") == Err(InvalidNumStr)
331expect Str.to_u16("-1") == Err(InvalidNumStr)
332expect Str.to_u16("not a number") == Err(InvalidNumStr)
333```
334
335to_i16 : Str -> Result I16 [InvalidNumStr]
336
337Description:
338Encode a [Str] to a signed [I16] integer. A [I16] value can hold numbers
339from `-32_768` to `32_767`. It can be
340specified with a i16 suffix.
341```roc
342expect Str.to_i16("1500") == Ok(1500i16)
343expect Str.to_i16("-1") == Ok(-1i16)
344expect Str.to_i16("0.1") == Err(InvalidNumStr)
345expect Str.to_i16("not a number") == Err(InvalidNumStr)
346```
347
348to_u8 : Str -> Result U8 [InvalidNumStr]
349
350Description:
351Encode a [Str] to an unsigned [U8] integer. A [U8] value can hold numbers
352from `0` to `255`. It can be specified with a u8 suffix.
353```roc
354expect Str.to_u8("250") == Ok(250u8)
355expect Str.to_u8("-0.1") == Err(InvalidNumStr)
356expect Str.to_u8("not a number") == Err(InvalidNumStr)
357expect Str.to_u8("1500") == Err(InvalidNumStr)
358```
359
360to_i8 : Str -> Result I8 [InvalidNumStr]
361
362Description:
363Encode a [Str] to a signed [I8] integer. A [I8] value can hold numbers
364from `-128` to `127`. It can be
365specified with a i8 suffix.
366```roc
367expect Str.to_i8("-15") == Ok(-15i8)
368expect Str.to_i8("150.00") == Err(InvalidNumStr)
369expect Str.to_i8("not a number") == Err(InvalidNumStr)
370```
371
372count_utf8_bytes : Str -> U64
373
374Description:
375Gives the number of bytes in a [Str] value.
376```roc
377expect Str.count_utf8_bytes("Hello World") == 11
378```
379
380replace_each : Str, Str, Str -> Str
381
382Description:
383Returns the given [Str] with each occurrence of a substring replaced.
384If the substring is not found, returns the original string.
385
386```roc
387expect Str.replace_each("foo/bar/baz", "/", "_") == "foo_bar_baz"
388expect Str.replace_each("not here", "/", "_") == "not here"
389```
390
391replace_first : Str, Str, Str -> Str
392
393Description:
394Returns the given [Str] with the first occurrence of a substring replaced.
395If the substring is not found, returns the original string.
396
397```roc
398expect Str.replace_first("foo/bar/baz", "/", "_") == "foo_bar/baz"
399expect Str.replace_first("no slashes here", "/", "_") == "no slashes here"
400```
401
402replace_last : Str, Str, Str -> Str
403
404Description:
405Returns the given [Str] with the last occurrence of a substring replaced.
406If the substring is not found, returns the original string.
407
408```roc
409expect Str.replace_last("foo/bar/baz", "/", "_") == "foo/bar_baz"
410expect Str.replace_last("no slashes here", "/", "_") == "no slashes here"
411```
412
413split_first : Str, Str -> Result { before : Str, after : Str } [NotFound]
414
415Description:
416Returns the given [Str] before the first occurrence of a [delimiter](https://www.computerhope.com/jargon/d/delimite.htm), as well
417as the rest of the string after that occurrence.
418Returns [Err NotFound] if the delimiter is not found.
419```roc
420expect Str.split_first("foo/bar/baz", "/") == Ok({ before: "foo", after: "bar/baz" })
421expect Str.split_first("no slashes here", "/") == Err(NotFound)
422```
423
424split_last : Str, Str -> Result { before : Str, after : Str } [NotFound]
425
426Description:
427Returns the given [Str] before the last occurrence of a delimiter, as well as
428the rest of the string after that occurrence.
429Returns [Err NotFound] if the delimiter is not found.
430```roc
431expect Str.split_last("foo/bar/baz", "/") == Ok({ before: "foo/bar", after: "baz" })
432expect Str.split_last("no slashes here", "/") == Err(NotFound)
433```
434
435walk_utf8_with_index : Str, state, (state, U8, U64 -> state) -> state
436
437Description:
438Walks over the `UTF-8` bytes of the given [Str] and calls a function to update
439state for each byte. The index for that byte in the string is provided
440to the update function.
441```roc
442f : List U8, U8, U64 -> List U8
443f = \state, byte, _ -> List.append(state, byte)
444expect Str.walk_utf8_with_index("ABC", [], f) == [65, 66, 67]
445```
446
447walk_utf8 : Str, state, (state, U8 -> state) -> state
448
449Description:
450Walks over the `UTF-8` bytes of the given [Str] and calls a function to update
451state for each byte.
452
453```roc
454sum_of_utf8_bytes =
455 Str.walk_utf8("Hello, World!", 0, (\total, byte ->
456 total + byte
457 ))
458
459expect sum_of_utf8_bytes == 105
460```
461
462release_excess_capacity : Str -> Str
463
464Description:
465Shrink the memory footprint of a str such that its capacity and length are equal.
466Note: This will also convert seamless slices to regular lists.
467
468with_prefix : Str, Str -> Str
469
470Description:
471Adds a prefix to the given [Str].
472```roc
473expect Str.with_prefix("Awesome", "Roc") == "RocAwesome"
474```
475
476contains : Str, Str -> Bool
477
478Description:
479Determines whether or not the first Str contains the second.
480```roc
481expect Str.contains("foobarbaz", "bar")
482expect !Str.contains("apple", "orange")
483expect Str.contains("anything", "")
484```
485
486drop_prefix : Str, Str -> Str
487
488Description:
489Drops the given prefix [Str] from the start of a [Str]
490If the prefix is not found, returns the original string.
491
492```roc
493expect Str.drop_prefix("bar", "foo") == "bar"
494expect Str.drop_prefix("foobar", "foo") == "bar"
495```
496
497drop_suffix : Str, Str -> Str
498
499Description:
500Drops the given suffix [Str] from the end of a [Str]
501If the suffix is not found, returns the original string.
502
503```roc
504expect Str.drop_suffix("bar", "foo") == "bar"
505expect Str.drop_suffix("barfoo", "foo") == "bar"
506```
507
508with_ascii_lowercased : Str -> Str
509
510Description:
511Lowercases ASCII characters only; non-ASCII left unchanged. For Unicode capitalization, use the `unicode` package. See [Str.caseless_ascii_equals] for case-insensitive comparison.
512```roc
513expect Str.with_ascii_lowercased("CAFÉ") == "cafÉ"
514```
515
516with_ascii_uppercased : Str -> Str
517
518Description:
519Uppercases ASCII characters only; non-ASCII left unchanged. For Unicode capitalization, use the `unicode` package. See [Str.caseless_ascii_equals] for case-insensitive comparison.
520```roc
521expect Str.with_ascii_uppercased("café") == "CAFé"
522```
523
524caseless_ascii_equals : Str, Str -> Bool
525
526Description:
527Case-insensitive comparison for ASCII characters only; non-ASCII must match exactly. See [Str.with_ascii_uppercased] and [Str.with_ascii_lowercased] for conversion.
528```roc
529expect Str.caseless_ascii_equals("café", "CAFé")
530expect !Str.caseless_ascii_equals("café", "CAFÉ") # é ≠ É (non-ASCII)
531```
532
533### Num
534
535`Num a` represents either an [Int] or [Frac]. Aliases: `Int a = Num (Integer a)`, `Frac a = Num (Fraction a)`.
536
537Untyped literals default to [I64] (integers) or [Dec] (decimals). Use suffixes for specific types: `215u8`, `76.4f32`, `123.45dec`.
538
539## Int Types
540
541Signed ([I8]-[I128]) can be negative; unsigned ([U8]-[U128]) cannot. Overflow crashes.
542
543| Type | Bytes | Range |
544|------|-------|-------|
545| I8/U8 | 1 | -128..127 / 0..255 |
546| I16/U16 | 2 | -32768..32767 / 0..65535 |
547| I32/U32 | 4 | ±2.1B / 0..4.3B |
548| I64/U64 | 8 | ±9.2×10¹⁸ / 0..1.8×10¹⁹ |
549| I128/U128 | 16 | ±1.7×10³⁸ / 0..3.4×10³⁸ |
550
551## Frac Types
552
553- [Dec]: 128-bit fixed-point, 18 decimal places. `0.1 + 0.2 == 0.3` (precise). Default for decimals.
554- [F32]/[F64]: Floating-point. Faster but imprecise: `0.1f64 + 0.2 != 0.3`. Has infinity/NaN.
555
556Special float values (IEEE-754): ∞ (pos/0.0), -∞ (neg/0.0), NaN (0.0/0.0). Check with #is_nan, #is_finite, #is_infinite.
557
558**Performance**: Dec add/sub similar to F64; Dec mul ~15x slower, div ~55x slower, trig ~2-4x slower. Use F64/F32 for performance-critical graphics/trig.
559
560e : Frac *
561
562Description:
563Euler's number (e)
564
565pi : Frac *
566
567Description:
568Archimedes' constant (π)
569
570tau : Frac *
571
572Description:
573Circle constant (τ)
574
575to_str : Num * -> Str
576
577Description:
578Convert a number to a [Str].
579
580```roc
581Num.to_str(42)
582```
583Only [Frac] values will include a decimal point, and they will always include one.
584```roc
585Num.to_str(4.2)
586Num.to_str(4.0)
587```
588When this function is given a non-[finite](Num#is_finite)
589[F64] or [F32] value, the returned string will be `"NaN"`, `"∞"`, or `"-∞"`.
590
591
592int_cast : Int a -> Int b
593
594Description:
595Convert an [Int] to a new [Int] of the expected type:
596
597```roc
598# Casts a U8 to a U16
599x : U16
600x = Num.int_cast(255u8)
601```
602
603In the case of downsizing, information is lost:
604
605```roc
606# returns 0, as the bits were truncated.
607x : U8
608x = Num.int_cast(256u16)
609```
610
611
612compare : Num a, Num a -> [ LT, EQ, GT ]
613
614is_lt : Num a, Num a -> Bool
615
616Description:
617Returns `Bool.true` if the first number is less than the second.
618
619`a < b` is shorthand for `Num.is_lt(a, b)`.
620
621If either argument is [*NaN*](Num#is_nan), returns `Bool.false` no matter what. (*NaN*
622is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
623```roc
6245
625 |> Num.is_lt 6
626```
627
628is_gt : Num a, Num a -> Bool
629
630Description:
631Returns `Bool.true` if the first number is greater than the second.
632
633`a > b` is shorthand for `Num.is_gt a b`.
634
635If either argument is [*NaN*](Num#is_nan), returns `Bool.false` no matter what. (*NaN*
636is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
637```roc
638Num.is_gt(6, 5)
639```
640
641is_lte : Num a, Num a -> Bool
642
643Description:
644Returns `Bool.true` if the first number is less than or equal to the second.
645
646`a <= b` is shorthand for `Num.is_lte(a, b)`.
647
648If either argument is [*NaN*](Num#is_nan), returns `Bool.false` no matter what. (*NaN*
649is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
650
651is_gte : Num a, Num a -> Bool
652
653Description:
654Returns `Bool.true` if the first number is greater than or equal to the second.
655
656`a >= b` is shorthand for `Num.is_gte(a, b)`.
657
658If either argument is [*NaN*](Num#is_nan), returns `Bool.false` no matter what. (*NaN*
659is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
660
661is_approx_eq : Frac a, Frac a, { rtol ? Frac a, atol ? Frac a } -> Bool
662
663Description:
664Returns `Bool.true` if the first number and second number are within a specific threshold
665
666A specific relative and absolute tolerance can be provided to change the threshold
667
668This function is symmetric: `Num.is_approx_eq(a, b) == Num.is_approx_eq(b, a)`
669
670If either argument is [*NaN*](Num#is_nan), returns `Bool.false` no matter what. (*NaN*
671is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
672
673is_zero : Num a -> Bool
674
675Description:
676Returns `Bool.true` if the number is `0`, and `Bool.false` otherwise.
677
678is_even : Int a -> Bool
679
680Description:
681A number is even if dividing it by 2 gives a remainder of 0.
682
683Examples of even numbers: 0, 2, 4, 6, 8, -2, -4, -6, -8
684
685is_odd : Int a -> Bool
686
687Description:
688A number is odd if dividing it by 2 gives a remainder of 1.
689
690Examples of odd numbers: 1, 3, 5, 7, -1, -3, -5, -7
691
692is_positive : Num a -> Bool
693
694Description:
695Positive numbers are greater than `0`.
696
697is_negative : Num a -> Bool
698
699Description:
700Negative numbers are less than `0`.
701
702to_frac : Num * -> Frac *
703
704is_nan : Frac * -> Bool
705
706Description:
707Returns `Bool.true` if the [Frac] is not a number as defined by [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
708
709```roc
710Num.is_nan(0 / 0)
711```
712
713is_infinite : Frac * -> Bool
714
715Description:
716Returns `Bool.true` if the [Frac] is positive or negative infinity as defined by [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
717
718```roc
719Num.is_infinite(1 / 0)
720
721Num.is_infinite(-1 / 0)
722```
723
724is_finite : Frac * -> Bool
725
726Description:
727Returns `Bool.true` if the [Frac] is not an infinity as defined by [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
728
729```roc
730Num.is_finite(42)
731```
732
733abs : Num a -> Num a
734
735Description:
736Returns the absolute value of the number.
737
738* For a positive number, returns the same number.
739* For a negative number, returns the same number except positive.
740* For zero, returns zero.
741```roc
742Num.abs(4)
743
744Num.abs(-2.5)
745
746Num.abs(0)
747
748Num.abs(0.0)
749```
750This is safe to use with any [Frac], but it can cause overflow when used with certain [Int] values.
751
752For example, calling #Num.abs on the lowest value of a signed integer (such as [Num.min_i64] or [Num.min_i32]) will cause overflow.
753This 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
754the highest value it can represent. (For this reason, calling [Num.neg] on the lowest signed value will also cause overflow.)
755
756Calling this on an unsigned integer (like [U32] or [U64]) never does anything.
757
758abs_diff : Num a, Num a -> Num a
759
760Description:
761Returns the absolute difference between two numbers.
762
763```roc
764Num.abs_diff(5, 3)
765
766Num.abs_diff(-3, 5)
767
768Num.abs_diff(3.0, 5.0)
769```
770
771If the answer to this operation can't fit in the return value (e.g. an
772[I8] answer that's higher than 127 or lower than -128), the result is an
773*overflow*. For [F64] and [F32], overflow results in an answer of either
774∞ or -∞. For all other number types, overflow results in a panic.
775
776neg : Num a -> Num a
777
778Description:
779Returns a negative number when given a positive one, and vice versa.
780```roc
781Num.neg(5)
782
783Num.neg(-2.5)
784
785Num.neg(0)
786
787Num.neg(0.0)
788```
789!! Num.neg is not completely implemented for all types in all contexts, see github.com/roc-lang/roc/issues/6959
790You can use `\some_num -> 0 - some_num` as a workaround.
791
792This is safe to use with any [Frac], but it can cause overflow when used with certain [Int] values.
793
794For example, calling #Num.neg on the lowest value of a signed integer (such as [Num.min_i64] or [Num.min_i32]) will cause overflow.
795This 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
796the highest value it can represent. (For this reason, calling #Num.abs on the lowest signed value will also cause overflow.)
797
798Additionally, calling #Num.neg on any unsigned integer (such as any [U64] or [U32] value) other than zero will cause overflow.
799
800(It will never crash when given a [Frac], however, because of how floating point numbers represent positive and negative numbers.)
801
802add : Num a, Num a -> Num a
803
804Description:
805Adds two numbers of the same type.
806
807(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.)
808
809`a + b` is shorthand for `Num.add(a, b)`.
810```roc
8115 + 7
812
813Num.add(5, 7)
814```
815`Num.add` can be convenient in pipelines.
816```roc
817Frac.pi
818 |> Num.add(1.0)
819```
820If the answer to this operation can't fit in the return value (e.g. an
821[I8] answer that's higher than 127 or lower than -128), the result is an
822*overflow*. For [F64] and [F32], overflow results in an answer of either
823∞ or -∞. For all other number types, overflow results in a panic.
824
825sub : Num a, Num a -> Num a
826
827Description:
828Subtracts two numbers of the same type.
829
830(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.)
831
832`a - b` is shorthand for `Num.sub(a, b)`.
833```roc
8347 - 5
835
836Num.sub(7, 5)
837```
838`Num.sub` can be convenient in pipelines.
839```roc
840Frac.pi
841 |> Num.sub(2.0)
842```
843If the answer to this operation can't fit in the return value (e.g. an
844[I8] answer that's higher than 127 or lower than -128), the result is an
845*overflow*. For [F64] and [F32], overflow results in an answer of either
846∞ or -∞. For all other number types, overflow results in a panic.
847
848mul : Num a, Num a -> Num a
849
850Description:
851Multiplies two numbers of the same type.
852
853(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.)
854
855`a * b` is shorthand for `Num.mul(a, b)`.
856```roc
8575 * 7
858
859Num.mul(5, 7)
860```
861
862`Num.mul` can be convenient in pipelines.
863
864```roc
865Frac.pi
866 |> Num.mul(2.0)
867```
868If the answer to this operation can't fit in the return value (e.g. an
869[I8] answer that's higher than 127 or lower than -128), the result is an
870*overflow*. For [F64] and [F32], overflow results in an answer of either
871∞ or -∞. For all other number types, overflow results in a panic.
872
873min : Num a, Num a -> Num a
874
875Description:
876Obtains the smaller between two numbers of the same type.
877
878```roc
879Num.min(100, 0)
880
881Num.min(3.0, -3.0)
882```
883
884max : Num a, Num a -> Num a
885
886Description:
887Obtains the greater between two numbers of the same type.
888
889```roc
890Num.max(100, 0)
891
892Num.max(3.0, -3.0)
893```
894
895sin : Frac a -> Frac a
896
897cos : Frac a -> Frac a
898
899tan : Frac a -> Frac a
900
901asin : Frac a -> Frac a
902
903acos : Frac a -> Frac a
904
905atan : Frac a -> Frac a
906
907sqrt : Frac a -> Frac a
908
909Description:
910Returns an approximation of the absolute value of a [Frac]'s square root.
911
912The square root of a negative number is an irrational number, and [Frac] only
913supports rational numbers. As such, you should make sure never to pass this
914function a negative number! Calling [sqrt] on a negative [Dec] will cause a panic.
915
916Calling [sqrt] on [F32] and [F64] values follows these rules:
917* Passing a negative [F64] or [F32] returns [*NaN*](Num#is_nan).
918* Passing [*NaN*](Num#is_nan) or -∞ also returns [*NaN*](Num#is_nan).
919* Passing ∞ returns ∞.
920
921> These rules come from the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
922> floating point standard. Because almost all modern processors are built to
923> this standard, deviating from these rules has a significant performance
924> cost! Since the most common reason to choose [F64] or [F32] over [Dec] is
925> access to hardware-accelerated performance, Roc follows these rules exactly.
926```roc
927Num.sqrt(4.0)
928
929Num.sqrt(1.5)
930
931Num.sqrt(0.0)
932
933Num.sqrt(-4.0f64)
934```
935
936sqrt_checked : Frac a -> Result (Frac a) [SqrtOfNegative]
937
938log : Frac a -> Frac a
939
940Description:
941Natural logarithm
942
943log_checked : Frac a -> Result (Frac a) [LogNeedsPositive]
944
945div : Frac a, Frac a -> Frac a
946
947Description:
948Divides one [Frac] by another.
949
950`a / b` is shorthand for `Num.div(a, b)`.
951
952[Division by zero is undefined in mathematics](https://en.wikipedia.org/wiki/Division_by_zero).
953As such, you should make sure never to pass zero as the denominator to this function!
954Calling [div] on a [Dec] denominator of zero will cause a panic.
955
956Calling [div] on [F32] and [F64] values follows these rules:
957* Dividing a positive [F64] or [F32] by zero returns ∞.
958* Dividing a negative [F64] or [F32] by zero returns -∞.
959* Dividing a zero [F64] or [F32] by zero returns [*NaN*](Num#is_nan).
960
961> These rules come from the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
962> floating point standard. Because almost all modern processors are built to
963> this standard, deviating from these rules has a significant performance
964> cost! Since the most common reason to choose [F64] or [F32] over [Dec] is
965> access to hardware-accelerated performance, Roc follows these rules exactly.
966
967To divide an [Int] and a [Frac], first convert the [Int] to a [Frac] using
968one of the functions in this module like #to_dec.
969```roc
9705.0 / 7.0
971
972Num.div(5, 7)
973```
974`Num.div` can be convenient in pipelines.
975```roc
976Num.pi
977 |> Num.div (2.0)
978```
979
980div_checked : Frac a, Frac a -> Result (Frac a) [DivByZero]
981
982div_ceil : Int a, Int a -> Int a
983
984div_ceil_checked : Int a, Int a -> Result (Int a) [DivByZero]
985
986div_trunc : Int a, Int a -> Int a
987
988Description:
989Divides two integers, truncating the result towards zero.
990
991`a // b` is shorthand for `Num.div_trunc(a, b)`.
992
993Division by zero is undefined in mathematics. As such, you should make
994sure never to pass zero as the denominator to this function! If you do,
995it will crash.
996```roc
9975 // 7
998
999Num.div_trunc(5, 7)
1000
10018 // -3
1002
1003Num.div_trunc(8, -3)
1004```
1005
1006div_trunc_checked : Int a, Int a -> Result (Int a) [DivByZero]
1007
1008rem : Int a, Int a -> Int a
1009
1010Description:
1011Obtains the remainder (truncating modulo) from the division of two integers.
1012
1013`a % b` is shorthand for `Num.rem(a, b)`.
1014```roc
10155 % 7
1016
1017Num.rem(5, 7)
1018
1019-8 % -3
1020
1021Num.rem(-8, -3)
1022```
1023
1024rem_checked : Int a, Int a -> Result (Int a) [DivByZero]
1025
1026is_multiple_of : Int a, Int a -> Bool
1027
1028bitwise_and : Int a, Int a -> Int a
1029
1030Description:
1031Does a "bitwise and". Each bit of the output is 1 if the corresponding bit
1032of x AND of y is 1, otherwise it's 0.
1033
1034bitwise_xor : Int a, Int a -> Int a
1035
1036Description:
1037Does a "bitwise exclusive or". Each bit of the output is the same as the
1038corresponding bit in x if that bit in y is 0, and it's the complement of
1039the bit in x if that bit in y is 1.
1040
1041bitwise_or : Int a, Int a -> Int a
1042
1043Description:
1044Does a "bitwise or". Each bit of the output is 0 if the corresponding bit
1045of x OR of y is 0, otherwise it's 1.
1046
1047bitwise_not : Int a -> Int a
1048
1049Description:
1050Returns the complement of x - the number you get by switching each 1 for a
10510 and each 0 for a 1. This is the same as -x - 1.
1052
1053shift_left_by : Int a, U8 -> Int a
1054
1055Description:
1056Bitwise left shift of a number by another
1057
1058The least significant bits always become 0. This means that shifting left is
1059like multiplying by factors of two for unsigned integers.
1060```roc
1061shift_left_by(0b0000_0011, 2) == 0b0000_1100
1062
10630b0000_0101 |> shift_left_by(2) == 0b0001_0100
1064```
1065In some languages `shift_left_by` is implemented as a binary operator `<<`.
1066
1067shift_right_by : Int a, U8 -> Int a
1068
1069Description:
1070Bitwise arithmetic shift of a number by another
1071
1072The most significant bits are copied from the current.
1073```roc
1074shift_right_by(0b0000_1100, 2) == 0b0000_0011
1075
10760b0001_0100 |> shift_right_by(2) == 0b0000_0101
1077
10780b1001_0000 |> shift_right_by(2) == 0b1110_0100
1079```
1080In some languages `shift_right_by` is implemented as a binary operator `>>>`.
1081
1082shift_right_zf_by : Int a, U8 -> Int a
1083
1084Description:
1085Bitwise logical right shift of a number by another
1086
1087The most significant bits always become 0. This means that shifting right is
1088like dividing by factors of two for unsigned integers.
1089```roc
1090shift_right_zf_by(0b0010_1000, 2) == 0b0000_1010
1091
10920b0010_1000 |> shift_right_zf_by(2) == 0b0000_1010
1093
10940b1001_0000 |> shift_right_zf_by(2) == 0b0010_0100
1095```
1096In some languages `shift_right_zf_by` is implemented as a binary operator `>>`.
1097
1098round : Frac * -> Int *
1099
1100Description:
1101Round off the given fraction to the nearest integer.
1102
1103floor : Frac * -> Int *
1104
1105ceiling : Frac * -> Int *
1106
1107pow : Frac a, Frac a -> Frac a
1108
1109Description:
1110Raises a [Frac] to the power of another [Frac].
1111
1112For an [Int] alternative to this function, see [Num.pow_int]
1113
1114pow_int : Int a, Int a -> Int a
1115
1116Description:
1117Raises an integer to the power of another, by multiplying the integer by
1118itself the given number of times.
1119
1120This process is known as [exponentiation by squaring](https://en.wikipedia.org/wiki/Exponentiation_by_squaring).
1121
1122For a [Frac] alternative to this function, which supports negative exponents,
1123see #Num.pow.
1124
1125## Warning
1126
1127It is very easy for this function to produce an answer
1128so large it causes an overflow.
1129
1130count_leading_zero_bits : Int a -> U8
1131
1132Description:
1133Counts the number of most-significant (leading in a big-Endian sense) zeroes in an integer.
1134
1135```roc
1136Num.count_leading_zero_bits(0b0001_1100u8)
1137
11383
1139
1140Num.count_leading_zero_bits(0b0000_0000u8)
1141
11428
1143```
1144
1145count_trailing_zero_bits : Int a -> U8
1146
1147Description:
1148Counts the number of least-significant (trailing in a big-Endian sense) zeroes in an integer.
1149
1150```roc
1151Num.count_trailing_zero_bits(0b0001_1100u8)
1152
11532
1154
1155Num.count_trailing_zero_bits(0b0000_0000u8)
1156
11578
1158```
1159
1160count_one_bits : Int a -> U8
1161
1162Description:
1163Counts the number of set bits in an integer.
1164
1165```roc
1166Num.count_one_bits(0b0001_1100u8)
1167
11683
1169
1170Num.count_one_bits(0b0000_0000u8)
1171
11720
1173```
1174
1175add_wrap : Int range, Int range -> Int range
1176
1177add_saturated : Num a, Num a -> Num a
1178
1179Description:
1180Adds two numbers, clamping on the maximum representable number rather than
1181overflowing.
1182
1183This is the same as [Num.add] except for the saturating behavior if the
1184addition is to overflow.
1185For example, if `x : U8` is 200 and `y : U8` is 100, `add_saturated x y` will
1186yield 255, the maximum value of a `U8`.
1187
1188add_checked : Num a, Num a -> Result (Num a) [Overflow]
1189
1190Description:
1191Adds two numbers and checks for overflow.
1192
1193This is the same as [Num.add] except if the operation overflows, instead of
1194panicking or returning ∞ or -∞, it will return `Err Overflow`.
1195
1196sub_wrap : Int range, Int range -> Int range
1197
1198sub_saturated : Num a, Num a -> Num a
1199
1200Description:
1201Subtracts two numbers, clamping on the minimum representable number rather
1202than overflowing.
1203
1204This is the same as [Num.sub] except for the saturating behavior if the
1205subtraction is to overflow.
1206For example, if `x : U8` is 10 and `y : U8` is 20, `sub_saturated x y` will
1207yield 0, the minimum value of a `U8`.
1208
1209sub_checked : Num a, Num a -> Result (Num a) [Overflow]
1210
1211Description:
1212Subtracts two numbers and checks for overflow.
1213
1214This is the same as [Num.sub] except if the operation overflows, instead of
1215panicking or returning ∞ or -∞, it will return `Err Overflow`.
1216
1217mul_wrap : Int range, Int range -> Int range
1218
1219mul_saturated : Num a, Num a -> Num a
1220
1221Description:
1222Multiplies two numbers, clamping on the maximum representable number rather than
1223overflowing.
1224
1225This is the same as [Num.mul] except for the saturating behavior if the
1226addition is to overflow.
1227
1228mul_checked : Num a, Num a -> Result (Num a) [Overflow]
1229
1230Description:
1231Multiplies two numbers and checks for overflow.
1232
1233This is the same as [Num.mul] except if the operation overflows, instead of
1234panicking or returning ∞ or -∞, it will return `Err Overflow`.
1235
1236
1237## Integer Type Bounds
1238
1239| Type | min | max |
1240|------|-----|-----|
1241| I8 | -128 | 127 |
1242| I16 | -32_768 | 32_767 |
1243| I32 | -2_147_483_648 | 2_147_483_647 |
1244| I64 | -9_223_372_036_854_775_808 | 9_223_372_036_854_775_807 |
1245| I128 | -170_141_183_460_469_231_731_687_303_715_884_105_728 | 170_141_183_460_469_231_731_687_303_715_884_105_727 |
1246| U8 | 0 | 255 |
1247| U16 | 0 | 65_535 |
1248| U32 | 0 | 4_294_967_295 |
1249| U64 | 0 | 18_446_744_073_709_551_615 |
1250| U128 | 0 | 340_282_366_920_938_463_463_374_607_431_768_211_455 |
1251
1252Functions: `min_i8`, `max_i8`, `min_u8`, `max_u8`, etc. for all integer types.
1253Also: `min_f32`, `max_f32`, `min_f64`, `max_f64` for float bounds.
1254
1255**Note**: For signed types, `|Num.abs(min_iN)|` > `max_iN`, so `Num.abs(min_iN)` will overflow.
1256
1257to_i8 : Int * -> I8
1258
1259Description:
1260Converts an [Int] to an [I8]. If the given number can't be precisely represented in an [I8],
1261the returned number may be different from the given number.
1262
1263to_i16 : Int * -> I16
1264
1265to_i32 : Int * -> I32
1266
1267to_i64 : Int * -> I64
1268
1269to_i128 : Int * -> I128
1270
1271to_u8 : Int * -> U8
1272
1273to_u16 : Int * -> U16
1274
1275to_u32 : Int * -> U32
1276
1277to_u64 : Int * -> U64
1278
1279to_u128 : Int * -> U128
1280
1281to_f32 : Num * -> F32
1282
1283Description:
1284Converts a [Num] to an [F32]. If the given number can't be precisely represented in an [F32],
1285the returned number may be different from the given number.
1286
1287to_f64 : Num * -> F64
1288
1289Description:
1290Converts a [Num] to an [F64]. If the given number can't be precisely represented in an [F64],
1291the returned number may be different from the given number.
1292
1293to_i8_checked : Int * -> Result I8 [OutOfBounds]
1294
1295Description:
1296Converts a [Int] to an [I8].
1297If the given integer can't be precisely represented in an [I8], returns
1298`Err OutOfBounds`.
1299
1300to_i16_checked : Int * -> Result I16 [OutOfBounds]
1301
1302to_i32_checked : Int * -> Result I32 [OutOfBounds]
1303
1304to_i64_checked : Int * -> Result I64 [OutOfBounds]
1305
1306to_i128_checked : Int * -> Result I128 [OutOfBounds]
1307
1308to_u8_checked : Int * -> Result U8 [OutOfBounds]
1309
1310to_u16_checked : Int * -> Result U16 [OutOfBounds]
1311
1312to_u32_checked : Int * -> Result U32 [OutOfBounds]
1313
1314to_u64_checked : Int * -> Result U64 [OutOfBounds]
1315
1316to_u128_checked : Int * -> Result U128 [OutOfBounds]
1317
1318to_f32_checked : Num * -> Result F32 [OutOfBounds]
1319
1320to_f64_checked : Num * -> Result F64 [OutOfBounds]
1321
1322without_decimal_point : Dec -> I128
1323
1324Description:
1325Turns a [Dec] into its [I128] representation by removing the decimal point.
1326This is equivalent to multiplying the [Dec] by 10^18.
1327
1328with_decimal_point : I128 -> Dec
1329
1330Description:
1331Turns a [I128] into the coresponding [Dec] by adding the decimal point.
1332This is equivalent to dividing the [I128] by 10^18.
1333
1334f32_to_parts : F32 -> { sign : Bool, exponent : U8, fraction : U32 }
1335
1336Description:
1337Splits a [F32] into its components according to IEEE 754 standard.
1338
1339This function is deprecated due to common pitfalls when working with float components
1340using Roc’s fixed-size integer types. Please use [Num.f32_to_bits] instead and extract the
1341[IEEE 754 parts](https://en.wikipedia.org/wiki/Single-precision_floating-point_format#IEEE_754_standard:_binary32)
1342manually from the resulting [U32].
1343
1344f64_to_parts : F64 -> { sign : Bool, exponent : U16, fraction : U64 }
1345
1346Description:
1347Splits a [F64] into its components according to IEEE 754 standard.
1348
1349This function is deprecated due to common pitfalls when working with float components
1350using Roc’s fixed-size integer types. Please use [Num.f64_to_bits] instead and extract the
1351[IEEE 754 parts](https://en.wikipedia.org/wiki/Double-precision_floating-point_format#IEEE_754_double-precision_binary_floating-point_format:_binary64)
1352manually from the resulting [U64].
1353
1354f32_from_parts : { sign : Bool, exponent : U8, fraction : U32 } -> F32
1355
1356Description:
1357Combine parts of a [F32] according to IEEE 754 standard.
1358The fraction should not be bigger than 0x007F_FFFF, any bigger value will be truncated.
1359
1360This function is deprecated due to common pitfalls when working with float components
1361using Roc’s fixed-size integer types. Please combine the
1362[IEEE 754 parts](https://en.wikipedia.org/wiki/Single-precision_floating-point_format#IEEE_754_standard:_binary32)
1363manually into a [U32] and use [Num.f32_from_bits] to create the [F32] instead.
1364
1365f64_from_parts : { sign : Bool, exponent : U16, fraction : U64 } -> F64
1366
1367Description:
1368Combine parts of a [F64] according to IEEE 754 standard.
1369The fraction should not be bigger than 0x000F_FFFF_FFFF_FFFF, any bigger value will be truncated.
1370The exponent should not be bigger than 0x07FF, any bigger value will be truncated.
1371
1372This function is deprecated due to common pitfalls when working with float components
1373using Roc’s fixed-size integer types. Please combine the
1374[IEEE 754 parts](https://en.wikipedia.org/wiki/Double-precision_floating-point_format#IEEE_754_double-precision_binary_floating-point_format:_binary64)
1375manually into a [U64] and use [Num.f64_from_bits] to create the [F64] instead.
1376
1377f32_to_bits : F32 -> U32
1378
1379Description:
1380Returns a [U32] containing the raw bits of a [F32], as defined by the IEEE 754 standard.
1381
1382f64_to_bits : F64 -> U64
1383
1384Description:
1385Returns a [U64] containing the raw bits of a [F64], as defined by the IEEE 754 standard.
1386
1387dec_to_bits : Dec -> U128
1388
1389Description:
1390Returns a [U128] containing the raw bits of a [Dec], which corresponds to the raw bits
1391of its [I128] representation.
1392
1393f32_from_bits : U32 -> F32
1394
1395Description:
1396Interprets a [U32] as the binary representation of a 32-bit floating-point value according
1397to the IEEE 754 standard and returns the corresponding [F32].
1398
1399f64_from_bits : U64 -> F64
1400
1401Description:
1402Interprets a [U64] as the binary representation of a 64-bit floating-point value according
1403to the IEEE 754 standard and returns the corresponding [F64].
1404
1405dec_from_bits : U128 -> Dec
1406
1407Description:
1408Interprets a [U128] as the raw bits of the internal [I128] representation of a fixed-point
1409decimal value and returns the corresponding [Dec].
1410
1411from_bool : Bool -> Num *
1412
1413Description:
1414Convert a `Bool` to a `Num`
1415```roc
1416expect Num.from_bool(Bool.true) == 1
1417expect Num.from_bool(Bool.false) == 0
1418```
1419
1420nan_f32 : F32
1421
1422Description:
1423The value for not-a-number for a [F32] according to the IEEE 754 standard.
1424
1425nan_f64 : F64
1426
1427Description:
1428The value for not-a-number for a [F64] according to the IEEE 754 standard.
1429
1430infinity_f32 : F32
1431
1432Description:
1433The value for infinity for a [F32] according to the IEEE 754 standard.
1434
1435infinity_f64 : F64
1436
1437Description:
1438The value for infinity for a [F64] according to the IEEE 754 standard.
1439
1440### Bool
1441
1442Eq : implements
1443 is_eq : a, a -> Bool
1444 where a implements Eq
1445
1446Description:
1447Defines a type that can be compared for total equality.
1448
1449Total equality means that all values of the type can be compared to each
1450other, and two values `a`, `b` are identical if and only if `is_eq(a, b)` is
1451`Bool.true`.
1452
1453Not all types support total equality. For example, [`F32`](Num#F32) and [`F64`](Num#F64) can
1454be a `NaN` ([Not a Number](https://en.wikipedia.org/wiki/NaN)), and the
1455[IEEE-754](https://en.wikipedia.org/wiki/IEEE_754) floating point standard
1456specifies that two `NaN`s are not equal.
1457
1458Description:
1459Represents the boolean true and false using an opaque type.
1460`Bool` implements the `Eq` ability.
1461
1462true : Bool
1463
1464Description:
1465The boolean true value.
1466
1467false : Bool
1468
1469Description:
1470The boolean false value.
1471
1472not : Bool -> Bool
1473
1474Description:
1475Returns `Bool.false` when given `Bool.true`, and vice versa. This is
1476equivalent to the logic [NOT](https://en.wikipedia.org/wiki/Negation)
1477gate. The operator `!` can also be used as shorthand for `Bool.not`.
1478```roc
1479expect Bool.not(Bool.false) == Bool.true
1480expect !Bool.false == Bool.true
1481```
1482
1483is_not_eq : a, a -> Bool where a implements Eq
1484
1485Description:
1486This will call the function `Bool.is_eq` on the inputs, and then `Bool.not`
1487on the result. The is equivalent to the logic
1488[XOR](https://en.wikipedia.org/wiki/Exclusive_or) gate. The infix operator
1489`!=` can also be used as shorthand for `Bool.is_not_eq`.
1490
1491**Note** that `is_not_eq` does not accept arguments whose types contain
1492functions.
1493```roc
1494expect Bool.is_not_eq(Bool.false, Bool.true) == Bool.true
1495expect (Bool.false != Bool.false) == Bool.false
1496expect "Apples" != "Oranges"
1497```
1498
1499### Result
1500
1501Result : [ Ok ok, Err err ]
1502
1503Description:
1504The result of an operation that could fail: either the operation went
1505okay, or else there was an error of some sort.
1506
1507is_ok : Result ok err -> Bool
1508
1509Description:
1510Returns `Bool.true` if the result indicates a success, else returns `Bool.false`.
1511```roc
1512Result.is_ok(Ok(5))
1513```
1514
1515is_err : Result ok err -> Bool
1516
1517Description:
1518Returns `Bool.true` if the result indicates a failure, else returns `Bool.false`.
1519```roc
1520Result.is_err(Err("uh oh"))
1521```
1522
1523with_default : Result ok err, ok -> ok
1524
1525Description:
1526If the result is `Ok`, returns the value it holds. Otherwise, returns
1527the given default value.
1528
1529Note: This function should be used sparingly, because it hides that an error
1530happened, which will make debugging harder. Prefer using `?` to forward errors or
1531handle them explicitly with `when`.
1532```roc
1533Result.with_default(Err("uh oh"), 42) # = 42
1534
1535Result.with_default(Ok(7), 42) # = 7
1536```
1537
1538map_ok : Result a err, (a -> b) -> Result b err
1539
1540Description:
1541If the result is `Ok`, transforms the value it holds by running a conversion
1542function on it. Then returns a new `Ok` holding the transformed value. If the
1543result is `Err`, this has no effect. Use [map_err] to transform an `Err`.
1544```roc
1545Result.map_ok(Ok(12), Num.neg) # = Ok(-12)
1546
1547Result.map_ok(Err("yipes!"), Num.neg) # = Err("yipes!")
1548```
1549Functions like `map` are common in Roc; see for example [List.map],
1550`Set.map`, and `Dict.map`.
1551
1552map_err : Result ok a, (a -> b) -> Result ok b
1553
1554Description:
1555If the result is `Err`, transforms the value it holds by running a conversion
1556function on it. Then returns a new `Err` holding the transformed value. If
1557the result is `Ok`, this has no effect. Use [map_ok] to transform an `Ok`.
1558```roc
1559List.last([]) |> Result.map_err(|_| ProvidedListIsEmpty) # = Err(ProvidedListIsEmpty)
1560
1561List.last([4]) |> Result.map_err(|_| ProvidedListIsEmpty) # = Ok(4)
1562```
1563
1564on_err : Result a err, (err -> Result a other_err) -> Result a other_err
1565
1566Description:
1567If the result is `Err`, transforms the entire result by running a conversion
1568function on the value the `Err` holds. Then returns that new result. If the
1569result is `Ok`, this has no effect. Use `?` or [try] to transform an `Ok`.
1570```roc
1571Result.on_err(Ok(10), Str.to_u64) # = Ok(10)
1572
1573Result.on_err(Err("42"), Str.to_u64) # = Ok(42)
1574
1575Result.on_err(Err("string"), Str.to_u64) # = Err(InvalidNumStr)
1576```
1577
1578on_err! : Result a err, (err => Result a other_err) => Result a other_err
1579
1580Description:
1581Like [on_err], but it allows the transformation function to produce effects.
1582
1583```roc
1584Result.on_err(
1585 Err("missing user"),
1586 |msg|
1587 Stdout.line!("ERROR: ${msg}")?
1588 Err(msg)
1589)
1590```
1591
1592map_both : Result ok1 err1, (ok1 -> ok2), (err1 -> err2) -> Result ok2 err2
1593
1594Description:
1595Maps both the `Ok` and `Err` values of a `Result` to new values.
1596
1597map2 : Result a err, Result b err, (a, b -> c) -> Result c err
1598
1599Description:
1600Maps the `Ok` values of two `Result`s to a new value using a given transformation,
1601or returns the first `Err` value encountered.
1602
1603try : Result a err, (a -> Result b err) -> Result b err
1604
1605Description:
1606If the result is `Ok`, transforms the entire result by running a conversion
1607function on the value the `Ok` holds. Then returns that new result. If the
1608result is `Err`, this has no effect.
1609
1610We recommend using `?` instead of `try`, it makes the code easier to read.
1611```roc
1612Result.try(Ok(-1), (|num| if num < 0 then Err("negative!") else Ok(-num))) # = Err("negative!")
1613
1614Result.try(Err("yipes!"), (|num| -> if num < 0 then Err("negative!") else Ok(-num))) # = Err("yipes!")
1615```
1616
1617### List
1618
1619is_empty : List * -> Bool
1620
1621Description:
1622 Check if the list is empty.
1623```roc
1624List.is_empty([1, 2, 3])
1625
1626List.is_empty([])
1627```
1628
1629get : List a, U64 -> Result a [OutOfBounds]
1630
1631Description:
1632Returns an element from a list at the given index.
1633
1634Returns `Err OutOfBounds` if the given index exceeds the List's length
1635```roc
1636expect List.get([100, 200, 300], 1) == Ok(200)
1637expect List.get([100, 200, 300], 5) == Err(OutOfBounds)
1638```
1639
1640replace : List a, U64, a -> { list : List a, value : a }
1641
1642set : List a, U64, a -> List a
1643
1644Description:
1645Replaces the element at the given index with a replacement.
1646```roc
1647List.set(["a", "b", "c"], 1, "B")
1648```
1649If the given index is outside the bounds of the list, returns the original
1650list unmodified.
1651
1652To drop the element at a given index, instead of replacing it, see [List.drop_at].
1653
1654update : List a, U64, (a -> a) -> List a
1655
1656Description:
1657Updates the element at the given index with the given function.
1658```roc
1659List.update([1, 2, 3], 1, (|x| x + 1))
1660```
1661If the given index is outside the bounds of the list, returns the original
1662list unmodified.
1663
1664To replace the element at a given index, instead of updating based on the current value,
1665see [List.set] and [List.replace]
1666
1667append : List a, a -> List a
1668
1669Description:
1670Add a single element to the end of a list.
1671```roc
1672List.append([1, 2, 3], 4)
1673
1674[0, 1, 2]
1675 |> List.append(3)
1676```
1677
1678append_if_ok : List a, Result a * -> List a
1679
1680Description:
1681If the given [Result] is `Ok`, add it to the end of a list.
1682Otherwise, return the list unmodified.
1683
1684```roc
1685List.append_if_ok([1, 2, 3], Ok(4))
1686
1687[0, 1, 2]
1688 |> List.append_if_ok(Err(3))
1689```
1690
1691prepend : List a, a -> List a
1692
1693Description:
1694Add a single element to the beginning of a list.
1695```roc
1696List.prepend([1, 2, 3], 0)
1697
1698[2, 3, 4]
1699 |> List.prepend(1)
1700```
1701
1702prepend_if_ok : List a, Result a * -> List a
1703
1704Description:
1705If the given [Result] is `Ok`, add it to the beginning of a list.
1706Otherwise, return the list unmodified.
1707
1708```roc
1709List.prepend([1, 2, 3], Ok(0))
1710
1711[2, 3, 4]
1712 |> List.prepend(Err(1))
1713```
1714
1715len : List * -> U64
1716
1717Description:
1718Returns the length of the list - the number of elements it contains.
1719
1720One [List] can store up to `Num.max_i64` elements on 64-bit targets and `Num.max_i32` on 32-bit targets like wasm.
1721This means the #U64 this function returns can always be safely converted to #I64 or #I32, depending on the target.
1722
1723with_capacity : U64 -> List *
1724
1725Description:
1726Create a list with space for at least capacity elements
1727
1728reserve : List a, U64 -> List a
1729
1730Description:
1731Enlarge the list for at least capacity additional elements
1732
1733release_excess_capacity : List a -> List a
1734
1735Description:
1736Shrink the memory footprint of a list such that it's capacity and length are equal.
1737Note: This will also convert seamless slices to regular lists.
1738
1739concat : List a, List a -> List a
1740
1741Description:
1742Put two lists together.
1743```roc
1744List.concat([1, 2, 3], [4, 5])
1745
1746[0, 1, 2]
1747 |> List.concat([3, 4])
1748```
1749
1750last : List a -> Result a [ListWasEmpty]
1751
1752Description:
1753Returns the last element in the list, or `ListWasEmpty` if it was empty.
1754```roc
1755expect List.last([1, 2, 3]) == Ok(3)
1756expect List.last([]) == Err(ListWasEmpty)
1757```
1758
1759single : a -> List a
1760
1761Description:
1762A list with a single element in it.
1763
1764This is useful in pipelines, like so:
1765```roc
1766websites =
1767 Str.concat(domain, ".com")
1768 |> List.single
1769```
1770
1771repeat : a, U64 -> List a
1772
1773Description:
1774Returns a list with the given length, where every element is the given value.
1775
1776reverse : List a -> List a
1777
1778Description:
1779Returns the list with its elements reversed.
1780```roc
1781expect List.reverse([1, 2, 3]) == [3, 2, 1]
1782```
1783
1784join : List (List a) -> List a
1785
1786Description:
1787Join the given lists together into one list.
1788```roc
1789expect List.join([[1], [2, 3], [], [4, 5]]) == [1, 2, 3, 4, 5]
1790expect List.join([[], []]) == []
1791expect List.join([]) == []
1792```
1793
1794contains : List a, a -> Bool where a implements Eq
1795
1796walk : List elem, state, (state, elem -> state) -> state
1797
1798Description:
1799Build a value by folding over list elements from first to last. Also known as `reduce`, `fold`, `foldl`.
1800```roc
1801[2, 4, 8] |> List.walk(0, Num.add) # returns 14
1802```
1803
1804walk_with_index : List elem, state, (state, elem, U64 -> state) -> state
1805
1806Description:
1807Like [walk], but at each step the function also receives the index of the current element.
1808
1809walk_with_index_until : List elem, state, (state, elem, U64 -> [ Continue state, Break state ]) -> state
1810
1811Description:
1812Like [walk_until], but at each step the function also receives the index of the current element.
1813
1814walk_backwards : List elem, state, (state, elem -> state) -> state
1815
1816Description:
1817Note that in other languages, `walk_backwards` is sometimes called `reduce_right`,
1818`fold`, `fold_right`, or `foldr`.
1819
1820walk_until : List elem, state, (state, elem -> [ Continue state, Break state ]) -> state
1821
1822Description:
1823Like [List.walk], but can stop early by returning `Break state`.
1824
1825walk_backwards_until : List elem, state, (state, elem -> [ Continue state, Break state ]) -> state
1826
1827Description:
1828Same as [List.walk_until], but does it from the end of the list instead.
1829
1830walk_from : List elem, U64, state, (state, elem -> state) -> state
1831
1832Description:
1833Walks to the end of the list from a specified starting index
1834
1835walk_from_until : List elem, U64, state, (state, elem -> [ Continue state, Break state ]) -> state
1836
1837Description:
1838A combination of [List.walk_from] and [List.walk_until]
1839
1840sum : List (Num a) -> Num a
1841
1842product : List (Num a) -> Num a
1843
1844any : List a, (a -> Bool) -> Bool
1845
1846Description:
1847Run the given predicate on each element of the list, returning `Bool.true` if
1848any of the elements satisfy it.
1849
1850all : List a, (a -> Bool) -> Bool
1851
1852Description:
1853Run the given predicate on each element of the list, returning `Bool.true` if
1854all of the elements satisfy it.
1855
1856keep_if : List a, (a -> Bool) -> List a
1857
1858Description:
1859Returns elements where the predicate returns `Bool.true`. Mutates in place if list is unique.
1860```roc
1861List.keep_if([1, 2, 3, 4], (|num| num > 2)) # [3, 4]
1862```
1863
1864
1865keep_if_try! : List a, (a => Result Bool err) => Result (List a) err
1866
1867Description:
1868Run an effectful function that returns a [Result] on each element of a list, and return all the
1869elements for which the function returned `Ok(Bool.true)`.
1870```roc
1871dirs_only = List.keep_if_try!(path_list, Path.is_dir!)?
1872```
1873
1874
1875drop_if : List a, (a -> Bool) -> List a
1876
1877Description:
1878Run the given function on each element of a list, and return all the
1879elements for which the function returned `Bool.false`.
1880```roc
1881List.drop_if([1, 2, 3, 4], (|num| num > 2))
1882```
1883## Performance Details
1884
1885`List.drop_if` has the same performance characteristics as [List.keep_if].
1886See its documentation for details on those characteristics!
1887
1888count_if : List a, (a -> Bool) -> U64
1889
1890Description:
1891Run the given function on each element of a list, and return the
1892number of elements for which the function returned `Bool.true`.
1893```roc
1894expect List.count_if([1, -2, -3], Num.is_negative) == 2
1895expect List.count_if([1, 2, 3], (|num| num > 1)) == 2
1896```
1897
1898keep_oks : List before, (before -> Result after *) -> List after
1899
1900Description:
1901This works like [List.map], except only the transformed values that are
1902wrapped in `Ok` are kept. Any that are wrapped in `Err` are dropped.
1903```roc
1904expect List.keep_oks(["1", "Two", "23", "Bird"], Str.to_i32) == [1, 23]
1905
1906expect List.keep_oks([["a", "b"], [], ["c", "d", "e"], [] ], List.first) == ["a", "c"]
1907
1908fn = |str| if Str.is_empty(str) then Err(StrWasEmpty) else Ok(str)
1909expect List.keep_oks(["", "a", "bc", "", "d", "ef", ""], fn) == ["a", "bc", "d", "ef"]
1910```
1911
1912keep_errs : List before, (before -> Result * after) -> List after
1913
1914Description:
1915This works like [List.map], except only the transformed values that are
1916wrapped in `Err` are kept. Any that are wrapped in `Ok` are dropped.
1917```roc
1918List.keep_errs([["a", "b"], [], [], ["c", "d", "e"]], List.last)
1919
1920fn = |str| if Str.is_empty(str) then Err(StrWasEmpty) else Okd(Str.len(str))
1921
1922List.keep_errs(["", "a", "bc", "", "d", "ef", ""], fn)
1923```
1924
1925map : List a, (a -> b) -> List b
1926
1927Description:
1928Convert each element in the list to something new, by calling a conversion
1929function on each of them. Then return a new list of the converted values.
1930```roc
1931expect List.map([1, 2, 3], (|num| num + 1)) == [2, 3, 4]
1932
1933expect List.map(["", "a", "bc"], Str.is_empty) == [Bool.true, Bool.false, Bool.false]
1934```
1935
1936map2 : List a, List b, (a, b -> c) -> List c
1937
1938Description:
1939Run a transformation function on the first element of each list,
1940and use that as the first element in the returned list.
1941Repeat until a list runs out of elements.
1942
1943Some languages have a function named `zip`, which does something similar to
1944calling [List.map2] passing two lists and `Pair`:
1945```roc
1946zipped = List.map2(["a", "b", "c"], [1, 2, 3], Pair)
1947```
1948
1949map3 : List a, List b, List c, (a, b, c -> d) -> List d
1950
1951Description:
1952Run a transformation function on the first element of each list,
1953and use that as the first element in the returned list.
1954Repeat until a list runs out of elements.
1955
1956map4 : List a, List b, List c, List d, (a, b, c, d -> e) -> List e
1957
1958Description:
1959Run a transformation function on the first element of each list,
1960and use that as the first element in the returned list.
1961Repeat until a list runs out of elements.
1962
1963map_with_index : List a, (a, U64 -> b) -> List b
1964
1965Description:
1966This works like [List.map], except it also passes the index
1967of the element to the conversion function.
1968```roc
1969expect List.map_with_index([10, 20, 30], (|num, index| num + index)) == [10, 21, 32]
1970```
1971
1972Description:
1973Returns a list of all the integers between `start` and `end`.
1974
1975To include the `start` and `end` integers themselves, use `At` like so:
1976```roc
1977List.range({ start: At 2, end: At 5 }) == [2, 3, 4, 5]
1978```
1979To exclude them, use `After` and `Before`, like so:
1980```roc
1981List.range({ start: After 2, end: Before 5 }) == [3, 4]
1982```
1983You can have the list end at a certain length rather than a certain integer:
1984```roc
1985List.range({ start: At 6, end: Length 4 }) == [6, 7, 8, 9]
1986```
1987If `step` is specified, each integer increases by that much. (`step: 1` is the default.)
1988```roc
1989List.range({ start: After 0, end: Before 9, step: 3 }) == [3, 6]
1990```
1991List.range will also generate a reversed list if step is negative or end comes before start:
1992```roc
1993List.range({ start: At 5, end: At 2 }) == [5, 4, 3, 2]
1994```
1995All of these options are compatible with the others. For example, you can use `At` or `After`
1996with `start` regardless of what `end` and `step` are set to.
1997
1998sort_with : List a, (a, a -> [ LT, EQ, GT ]) -> List a
1999
2000Description:
2001Sort with a custom comparison function
2002
2003sort_asc : List (Num a) -> List (Num a)
2004
2005Description:
2006Sorts a list of numbers in ascending order (lowest to highest).
2007
2008To sort in descending order (highest to lowest), use [List.sort_desc] instead.
2009
2010sort_desc : List (Num a) -> List (Num a)
2011
2012Description:
2013Sorts a list of numbers in descending order (highest to lowest).
2014
2015To sort in ascending order (lowest to highest), use [List.sort_asc] instead.
2016
2017swap : List a, U64, U64 -> List a
2018
2019first : List a -> Result a [ListWasEmpty]
2020
2021Description:
2022Returns the first element in the list, or `ListWasEmpty` if it was empty.
2023
2024take_first : List elem, U64 -> List elem
2025
2026Description:
2027Returns the given number of elements from the beginning of the list.
2028```roc
2029List.take_first([1, 2, 3, 4, 5, 6, 7, 8], 4) == [1, 2, 3, 4]
2030```
2031If there are fewer elements in the list than the requested number,
2032returns the entire list.
2033```roc
2034List.take_first([1, 2], 5) == [1, 2]
2035```
2036To *remove* elements from the beginning of the list, use `List.take_last`.
2037
2038To remove elements from both the beginning and end of the list,
2039use `List.sublist`.
2040
2041To split the list into two lists, use `List.split_at`.
2042
2043
2044take_last : List elem, U64 -> List elem
2045
2046Description:
2047Returns the given number of elements from the end of the list.
2048```roc
2049List.take_last([1, 2, 3, 4, 5, 6, 7, 8], 4) == [5, 6, 7, 8]
2050```
2051If there are fewer elements in the list than the requested number,
2052returns the entire list.
2053```roc
2054List.take_last([1, 2], 5) == [1, 2]
2055```
2056To *remove* elements from the end of the list, use `List.take_first`.
2057
2058To remove elements from both the beginning and end of the list,
2059use `List.sublist`.
2060
2061To split the list into two lists, use `List.split_at`.
2062
2063
2064drop_first : List elem, U64 -> List elem
2065
2066Description:
2067Drops n elements from the beginning of the list.
2068
2069drop_last : List elem, U64 -> List elem
2070
2071Description:
2072Drops n elements from the end of the list.
2073
2074drop_at : List elem, U64 -> List elem
2075
2076Description:
2077Drops the element at the given index from the list.
2078
2079This has no effect if the given index is outside the bounds of the list.
2080
2081To replace the element at a given index, instead of dropping it, see [List.set].
2082
2083min : List (Num a) -> Result (Num a) [ListWasEmpty]
2084
2085max : List (Num a) -> Result (Num a) [ListWasEmpty]
2086
2087join_map : List a, (a -> List b) -> List b
2088
2089Description:
2090Like [List.map], except the transformation function wraps the return value
2091in a list. At the end, all the lists get joined together into one list.
2092
2093You may know a similar function named `concat_map` in other languages.
2094
2095find_first : List elem, (elem -> Bool) -> Result elem [NotFound]
2096
2097Description:
2098Returns the first element of the list satisfying a predicate function.
2099If no satisfying element is found, an `Err NotFound` is returned.
2100
2101find_last : List elem, (elem -> Bool) -> Result elem [NotFound]
2102
2103Description:
2104Returns the last element of the list satisfying a predicate function.
2105If no satisfying element is found, an `Err NotFound` is returned.
2106
2107find_first_index : List elem, (elem -> Bool) -> Result U64 [NotFound]
2108
2109Description:
2110Returns the index at which the first element in the list
2111satisfying a predicate function can be found.
2112If no satisfying element is found, an `Err NotFound` is returned.
2113
2114find_last_index : List elem, (elem -> Bool) -> Result U64 [NotFound]
2115
2116Description:
2117Returns the last index at which the first element in the list
2118satisfying a predicate function can be found.
2119If no satisfying element is found, an `Err NotFound` is returned.
2120
2121sublist : List elem, { start : U64, len : U64 } -> List elem
2122
2123Description:
2124Returns a subsection of the given list, beginning at the `start` index and
2125including a total of `len` elements.
2126
2127If `start` is outside the bounds of the given list, returns the empty list.
2128```roc
2129List.sublist([1, 2, 3], { start: 4, len: 0 })
2130```
2131If more elements are requested than exist in the list, returns as many as it can.
2132```roc
2133List.sublist([1, 2, 3, 4, 5], { start: 2, len: 10 })
2134```
2135> If you want a sublist which goes all the way to the end of the list, no
2136> matter how long the list is, `List.take_last` can do that more efficiently.
2137
2138Some languages have a function called **`slice`** which works similarly to this.
2139
2140intersperse : List elem, elem -> List elem
2141
2142Description:
2143Intersperses `sep` between the elements of `list`
2144```roc
2145List.intersperse([1, 2, 3], 9) == [1, 9, 2, 9, 3]
2146```
2147
2148starts_with : List elem, List elem -> Bool where elem implements Eq
2149
2150Description:
2151Returns `Bool.true` if the first list starts with the second list.
2152
2153If the second list is empty, this always returns `Bool.true`; every list
2154is considered to "start with" an empty list.
2155
2156If the first list is empty, this only returns `Bool.true` if the second list is empty.
2157
2158ends_with : List elem, List elem -> Bool where elem implements Eq
2159
2160Description:
2161Returns `Bool.true` if the first list ends with the second list.
2162
2163If the second list is empty, this always returns `Bool.true`; every list
2164is considered to "end with" an empty list.
2165
2166If the first list is empty, this only returns `Bool.true` if the second list is empty.
2167
2168split_at : List elem, U64 -> { before : List elem, others : List elem }
2169
2170Description:
2171Splits the list into two lists, around the given index.
2172
2173The returned lists are labeled `before` and `others`. The `before` list will
2174contain all the elements whose index in the original list was **less than**
2175than the given index, # and the `others` list will be all the others. (This
2176means if you give an index of 0, the `before` list will be empty and the
2177`others` list will have the same elements as the original list.)
2178
2179split_on : List a, a -> List (List a) where a implements Eq
2180
2181Description:
2182Splits the input list on the delimiter element.
2183
2184```roc
2185List.split_on([1, 2, 3], 2) == [[1], [3]]
2186```
2187
2188split_on_list : List a, List a -> List (List a) where a implements Eq
2189
2190Description:
2191Splits the input list on the delimiter list.
2192
2193```roc
2194List.split_on_list([1, 2, 3], [1, 2]) == [[], [3]]
2195```
2196
2197split_first : List elem, elem -> Result { before : List elem, after : List elem } [NotFound] where elem implements Eq
2198
2199Description:
2200Returns the elements before the first occurrence of a delimiter, as well as the
2201remaining elements after that occurrence. If the delimiter is not found, returns `Err`.
2202```roc
2203List.split_first([Foo, Z, Bar, Z, Baz], Z) == Ok({ before: [Foo], after: [Bar, Z, Baz] })
2204```
2205
2206split_last : List elem, elem -> Result { before : List elem, after : List elem } [NotFound] where elem implements Eq
2207
2208Description:
2209Returns the elements before the last occurrence of a delimiter, as well as the
2210remaining elements after that occurrence. If the delimiter is not found, returns `Err`.
2211```roc
2212List.split_last([Foo, Z, Bar, Z, Baz], Z) == Ok({ before: [Foo, Z, Bar], after: [Baz] })
2213```
2214
2215chunks_of : List a, U64 -> List (List a)
2216
2217Description:
2218Splits the list into many chunks, each of which is length of the given chunk
2219size. The last chunk will be shorter if the list does not evenly divide by the
2220chunk size. If the provided list is empty or if the chunk size is 0 then the
2221result is an empty list.
2222
2223map_try : List elem, (elem -> Result ok err) -> Result (List ok) err
2224
2225Description:
2226Like [List.map], except the transformation function returns a [Result].
2227If that function ever returns `Err`, [map_try] immediately returns that `Err`.
2228If it returns `Ok` for every element, [map_try] returns `Ok` with the transformed list.
2229
2230map_try! : List elem, (elem => Result ok err) => Result (List ok) err
2231
2232Description:
2233Like [List.map_try], but with an effectful function.
2234```
2235file_list = ["a.txt", "b.txt", "c.txt"]
2236file_contents =
2237 List.map_try!(file_list, |file| File.read_utf8!(file))
2238```
2239
2240walk_try : List elem, state, (state, elem -> Result state err) -> Result state err
2241
2242Description:
2243Like [List.walk], but stops early and returns `Err` if the function returns `Err`.
2244
2245concat_utf8 : List U8, Str -> List U8
2246
2247Description:
2248Concatenates the bytes of a string encoded as utf8 to a list of bytes.
2249```roc
2250expect List.concat_utf8([1, 2, 3, 4], "🐦") == [1, 2, 3, 4, 240, 159, 144, 166]
2251```
2252
2253for_each! : List a, (a => {}) => {}
2254
2255Description:
2256Run an effectful function for each element on the list.
2257
2258```roc
2259List.for_each!(["Alice", "Bob", "Charlie"], |name|
2260 create_account!(name)
2261 log!("Account created")
2262)
2263```
2264
2265If the function might fail or you need to return early, use [for_each_try!].
2266
2267for_each_try! : List a, (a => Result {} err) => Result {} err
2268
2269Description:
2270Run an effectful function that might fail for each element on the list.
2271
2272If the function returns `Err`, the iteration stops and the error is returned.
2273
2274```roc
2275List.for_each_try!(files_to_delete, |path|
2276 File.delete!(path)?
2277
2278 Stdout.line!("${path} deleted")
2279)
2280```
2281
2282walk! : List elem, state, (state, elem => state) => state
2283
2284Description:
2285Build a value from the contents of a list, using an effectful function.
2286
2287```roc
2288now_multiples = List.walk!([1, 2, 3], [], |nums, i|
2289 now = Utc.now!({}) |> Utc.to_millis_since_epoch
2290 List.append(nums, now * i)
2291)
2292```
2293
2294This is the same as [walk], except that the step function can have effects.
2295
2296walk_try! : List elem, state, (state, elem => Result state err) => Result state err
2297
2298Description:
2299Build a value from the contents of a list, using an effectful function that might fail.
2300
2301If the function returns `Err`, the iteration stops and the error is returned.
2302
2303```
2304names =
2305 List.walk_try!(
2306 ["First", "Middle", "Last"],
2307 [],
2308 |accumulator, which|
2309 Stdout.write!("${which} name: ")?
2310 name = Stdin.line!({})?
2311 Ok(List.append(accumulator, name)),
2312 )?
2313```
2314
2315This is the same as [walk_try], except that the step function can have effects.
2316
2317### Dict
2318
2319Associative array mapping keys to values. Maintains insertion order for [Dict.keys]/[Dict.values], but [Dict.remove] moves last element into removed slot (O(1) removal). Based on IndexMap/unordered_dense.
2320```roc
2321Dict.empty({}) |> Dict.insert("London", 8_961_989) |> Dict.get("London") # Ok(8_961_989)
2322```
2323
2324empty : {} -> Dict * *
2325
2326Description:
2327Return an empty dictionary.
2328```roc
2329empty_dict = Dict.empty({})
2330```
2331
2332with_capacity : U64 -> Dict * *
2333
2334Description:
2335Return a dictionary with space allocated for a number of entries. This
2336may provide a performance optimization if you know how many entries will be
2337inserted.
2338
2339reserve : Dict k v, U64 -> Dict k v
2340
2341Description:
2342Enlarge the dictionary for at least capacity additional elements
2343
2344release_excess_capacity : Dict k v -> Dict k v
2345
2346Description:
2347Shrink the memory footprint of a dictionary such that capacity is as small as possible.
2348This function will require regenerating the metadata if the size changes.
2349There will still be some overhead due to dictionary metadata always being a power of 2.
2350
2351capacity : Dict * * -> U64
2352
2353Description:
2354Returns the max number of elements the dictionary can hold before requiring a rehash.
2355```roc
2356food_dict =
2357 Dict.empty({})
2358 |> Dict.insert("apple", "fruit")
2359
2360capacity_of_dict = Dict.capacity(food_dict)
2361```
2362
2363single : k, v -> Dict k v
2364
2365Description:
2366Returns a dictionary containing the key and value provided as input.
2367```roc
2368expect
2369 Dict.single("A", "B")
2370 |> Bool.is_eq(Dict.empty({}) |> Dict.insert("A", "B"))
2371```
2372
2373from_list : List ( k, v ) -> Dict k v
2374
2375Description:
2376Returns dictionary with the keys and values specified by the input [List].
2377```roc
2378expect
2379 Dict.single(1, "One")
2380 |> Dict.insert(2, "Two")
2381 |> Dict.insert(3, "Three")
2382 |> Dict.insert(4, "Four")
2383 |> Bool.is_eq(Dict.from_list([(1, "One"), (2, "Two"), (3, "Three"), (4, "Four")]))
2384```
2385
2386## Performance Details
2387
2388This will build up from an empty dictionary to minimize totally memory use.
2389If the list has few duplicate keys, it would be faster to allocate a dictionary
2390with the same capacity of the list and walk it calling [Dict.insert]
2391
2392len : Dict * * -> U64
2393
2394Description:
2395Returns the number of values in the dictionary.
2396```roc
2397expect
2398 Dict.empty({})
2399 |> Dict.insert("One", "A Song")
2400 |> Dict.insert("Two", "Candy Canes")
2401 |> Dict.insert("Three", "Boughs of Holly")
2402 |> Dict.len
2403 |> Bool.is_eq(3)
2404```
2405
2406is_empty : Dict * * -> Bool
2407
2408Description:
2409Check if the dictionary is empty.
2410```roc
2411Dict.is_empty(Dict.empty({}) |> Dict.insert("key", 42))
2412
2413Dict.is_empty(Dict.empty({}))
2414```
2415
2416clear : Dict k v -> Dict k v
2417
2418Description:
2419Clears all elements from a dictionary keeping around the allocation if it isn't huge.
2420```roc
2421songs =
2422 Dict.empty({})
2423 |> Dict.insert("One", "A Song")
2424 |> Dict.insert("Two", "Candy Canes")
2425 |> Dict.insert("Three", "Boughs of Holly")
2426
2427clear_songs = Dict.clear(songs)
2428
2429expect Dict.len(clear_songs) == 0
2430```
2431
2432map : Dict k a, (k, a -> b) -> Dict k b
2433
2434Description:
2435Convert each value in the dictionary to something new, by calling a conversion
2436function on each of them which receives both the key and the old value. Then return a
2437new dictionary containing the same keys and the converted values.
2438
2439join_map : Dict a b, (a, b -> Dict x y) -> Dict x y
2440
2441Description:
2442Like [Dict.map], except the transformation function wraps the return value
2443in a dictionary. At the end, all the dictionaries get joined together
2444(using [Dict.insert_all]) into one dictionary.
2445
2446You may know a similar function named `concat_map` in other languages.
2447
2448walk : Dict k v, state, (state, k, v -> state) -> state
2449
2450Description:
2451Iterate through the keys and values in the dictionary and call the provided
2452function with signature `state, k, v -> state` for each value, with an
2453initial `state` value provided for the first call.
2454```roc
2455expect
2456 Dict.empty({})
2457 |> Dict.insert("Apples", 12)
2458 |> Dict.insert("Orange", 24)
2459 |> Dict.walk(0, (\count, _, qty -> count + qty))
2460 |> Bool.is_eq(36)
2461```
2462
2463walk_until : Dict k v, state, (state, k, v -> [ Continue state, Break state ]) -> state
2464
2465Description:
2466Like [Dict.walk], but can stop early by returning `Break state`.
2467
2468keep_if : Dict k v, ( ( k, v ) -> Bool) -> Dict k v
2469
2470Description:
2471Run the given function on each key-value pair of a dictionary, and return
2472a dictionary with just the pairs for which the function returned `Bool.true`.
2473```roc
2474expect Dict.empty({})
2475 |> Dict.insert("Alice", 17)
2476 |> Dict.insert("Bob", 18)
2477 |> Dict.insert("Charlie", 19)
2478 |> Dict.keep_if(\(_k, v) -> v >= 18)
2479 |> Dict.len
2480 |> Bool.is_eq(2)
2481```
2482
2483drop_if : Dict k v, ( ( k, v ) -> Bool) -> Dict k v
2484
2485Description:
2486Run the given function on each key-value pair of a dictionary, and return
2487a dictionary with just the pairs for which the function returned `Bool.false`.
2488```roc
2489expect Dict.empty({})
2490 |> Dict.insert("Alice", 17)
2491 |> Dict.insert("Bob", 18)
2492 |> Dict.insert("Charlie", 19)
2493 |> Dict.drop_if(\(_k, v) -> v >= 18)
2494 |> Dict.len
2495 |> Bool.is_eq(1)
2496```
2497
2498get : Dict k v, k -> Result v [KeyNotFound]
2499
2500Description:
2501Get the value for a given key. If there is a value for the specified key it
2502will return [Ok value], otherwise return [Err KeyNotFound].
2503```roc
2504dictionary =
2505 Dict.empty({})
2506 |> Dict.insert(1,s "Apple")
2507 |> Dict.insert(2,s "Orange")
2508
2509expect Dict.get(dictionary, 1) == Ok("Apple")
2510expect Dict.get(dictionary, 2000) == Err(KeyNotFound)
2511```
2512
2513contains : Dict k v, k -> Bool
2514
2515Description:
2516Check if the dictionary has a value for a specified key.
2517```roc
2518expect
2519 Dict.empty({})
2520 |> Dict.insert(1234, "5678")
2521 |> Dict.contains(1234)
2522 |> Bool.is_eq(Bool.true)
2523```
2524
2525insert : Dict k v, k, v -> Dict k v
2526
2527Description:
2528Insert a value into the dictionary at a specified key.
2529```roc
2530expect
2531 Dict.empty({})
2532 |> Dict.insert("Apples", 12)
2533 |> Dict.get("Apples")
2534 |> Bool.is_eq(Ok(12))
2535```
2536
2537remove : Dict k v, k -> Dict k v
2538
2539Description:
2540Remove a value from the dictionary for a specified key.
2541```roc
2542expect
2543 Dict.empty({})
2544 |> Dict.insert("Some", "Value")
2545 |> Dict.remove("Some")
2546 |> Dict.len
2547 |> Bool.is_eq(0)
2548```
2549
2550update : Dict k v, k, (Result v [Missing] -> Result v [Missing]) -> Dict k v
2551
2552Description:
2553Insert or remove a value for a specified key. This function enables a
2554performance optimization for the use case of providing a default when a value
2555is missing. This is more efficient than doing both a `Dict.get` and then a
2556`Dict.insert` call, and supports being piped.
2557```roc
2558alter_value : Result Bool [Missing] -> Result Bool [Missing]
2559alter_value = \possible_value ->
2560 when possible_value is
2561 Err Missing -> Ok(Bool.false)
2562 Ok value -> if value then Err(Missing) else Ok(Bool.true)
2563
2564expect Dict.update(Dict.empty({}), "a", alter_value) == Dict.single("a", Bool.false)
2565expect Dict.update(Dict.single("a", Bool.false), "a", alter_value) == Dict.single("a", Bool.true)
2566expect Dict.update(Dict.single("a", Bool.true), "a", alter_value) == Dict.empty({})
2567```
2568
2569to_list : Dict k v -> List ( k, v )
2570
2571Description:
2572Returns the keys and values of a dictionary as a [List].
2573This requires allocating a temporary list, prefer using [Dict.to_list] or [Dict.walk] instead.
2574```roc
2575expect
2576 Dict.single(1, "One")
2577 |> Dict.insert(2, "Two")
2578 |> Dict.insert(3, "Three")
2579 |> Dict.insert(4, "Four")
2580 |> Dict.to_list
2581 |> Bool.is_eq([(1, "One"), (2, "Two"), (3, "Three"), (4, "Four")])
2582```
2583
2584keys : Dict k v -> List k
2585
2586Description:
2587Returns the keys of a dictionary as a [List].
2588This requires allocating a temporary [List], prefer using [Dict.to_list] or [Dict.walk] instead.
2589```roc
2590expect
2591 Dict.single(1, "One")
2592 |> Dict.insert(2, "Two")
2593 |> Dict.insert(3, "Three")
2594 |> Dict.insert(4, "Four")
2595 |> Dict.keys
2596 |> Bool.is_eq([1,2,3,4])
2597```
2598
2599values : Dict k v -> List v
2600
2601Description:
2602Returns the values of a dictionary as a [List].
2603This requires allocating a temporary [List], prefer using [Dict.to_list] or [Dict.walk] instead.
2604```roc
2605expect
2606 Dict.single(1, "One")
2607 |> Dict.insert(2, "Two")
2608 |> Dict.insert(3, "Three")
2609 |> Dict.insert(4, "Four")
2610 |> Dict.values
2611 |> Bool.is_eq(["One","Two","Three","Four"])
2612```
2613
2614insert_all : Dict k v, Dict k v -> Dict k v
2615
2616Description:
2617Combine two dictionaries by keeping the [union](https://en.wikipedia.org/wiki/Union_(set_theory))
2618of all the key-value pairs. This means that all the key-value pairs in
2619both dictionaries will be combined. Note that where there are pairs
2620with the same key, the value contained in the second input will be
2621retained, and the value in the first input will be removed.
2622```roc
2623first =
2624 Dict.single(1, "Not Me")
2625 |> Dict.insert(2, "And Me")
2626
2627second =
2628 Dict.single(1, "Keep Me")
2629 |> Dict.insert(3, "Me Too")
2630 |> Dict.insert(4, "And Also Me")
2631
2632expected =
2633 Dict.single(1, "Keep Me")
2634 |> Dict.insert(2, "And Me")
2635 |> Dict.insert(3, "Me Too")
2636 |> Dict.insert(4, "And Also Me")
2637
2638expect
2639 Dict.insert_all(first, second) == expected
2640```
2641
2642keep_shared : Dict k v, Dict k v -> Dict k v where v implements Eq
2643
2644Description:
2645Combine two dictionaries by keeping the [intersection](https://en.wikipedia.org/wiki/Intersection_(set_theory))
2646of all the key-value pairs. This means that we keep only those pairs
2647that are in both dictionaries. Both the key and value must match to be kept.
2648```roc
2649first =
2650 Dict.single(1, "Keep Me")
2651 |> Dict.insert(2, "And Me")
2652 |> Dict.insert(3, "Not this one")
2653
2654second =
2655 Dict.single(1, "Keep Me")
2656 |> Dict.insert(2, "And Me")
2657 |> Dict.insert(3, "This has a different value")
2658 |> Dict.insert(4, "Or Me")
2659
2660expected =
2661 Dict.single(1, "Keep Me")
2662 |> Dict.insert(2, "And Me")
2663
2664expect Dict.keep_shared(first, second) == expected
2665```
2666
2667remove_all : Dict k v, Dict k v -> Dict k v
2668
2669Description:
2670Remove the key-value pairs in the first input that are also in the second
2671using the [set difference](https://en.wikipedia.org/wiki/Complement_(set_theory)#Relative_complement)
2672of the values. This means that we will be left with only those pairs that
2673are in the first dictionary and whose keys are not in the second.
2674```roc
2675first =
2676 Dict.single(1, "Keep Me")
2677 |> Dict.insert(2, "And Me")
2678 |> Dict.insert(3, "Remove Me")
2679
2680second =
2681 Dict.single(3, "Remove Me")
2682 |> Dict.insert(4, "I do nothing...")
2683
2684expected =
2685 Dict.single(1, "Keep Me")
2686 |> Dict.insert(2, "And Me")
2687
2688expect Dict.remove_all(first, second) == expected
2689```
2690
2691### Set
2692
2693Description:
2694Provides a [set](https://en.wikipedia.org/wiki/Set_(abstract_data_type))
2695type which stores a collection of unique values, without any ordering
2696
2697empty : {} -> Set *
2698
2699Description:
2700Creates a new empty `Set`.
2701```roc
2702empty_set = Set.empty({})
2703count_values = Set.len(empty_set)
2704
2705expect count_values == 0
2706```
2707
2708with_capacity : U64 -> Set *
2709
2710Description:
2711Return a set with space allocated for a number of entries. This
2712may provide a performance optimization if you know how many entries will be
2713inserted.
2714
2715reserve : Set k, U64 -> Set k
2716
2717Description:
2718Enlarge the set for at least capacity additional elements
2719
2720release_excess_capacity : Set k -> Set k
2721
2722Description:
2723Shrink the memory footprint of a set such that capacity is as small as possible.
2724This function will require regenerating the metadata if the size changes.
2725There will still be some overhead due to dictionary metadata always being a power of 2.
2726
2727single : k -> Set k
2728
2729Description:
2730Creates a new `Set` with a single value.
2731```roc
2732single_item_set = Set.single("Apple")
2733count_values = Set.len(single_item_set)
2734
2735expect count_values == 1
2736```
2737
2738insert : Set k, k -> Set k
2739
2740Description:
2741Insert a value into a `Set`.
2742```roc
2743few_item_set =
2744 Set.empty({})
2745 |> Set.insert("Apple")
2746 |> Set.insert("Pear")
2747 |> Set.insert("Banana")
2748
2749count_values = Set.len(few_item_set)
2750
2751expect count_values == 3
2752```
2753
2754len : Set * -> U64
2755
2756Description:
2757Counts the number of values in a given `Set`.
2758```roc
2759few_item_set =
2760 Set.empty({})
2761 |> Set.insert("Apple")
2762 |> Set.insert("Pear")
2763 |> Set.insert("Banana")
2764
2765count_values = Set.len(few_item_set)
2766
2767expect count_values == 3
2768```
2769
2770capacity : Set * -> U64
2771
2772Description:
2773Returns the max number of elements the set can hold before requiring a rehash.
2774```roc
2775food_set =
2776 Set.empty({})
2777 |> Set.insert("apple")
2778
2779capacity_of_set = Set.capacity(food_set)
2780```
2781
2782is_empty : Set * -> Bool
2783
2784Description:
2785Check if the set is empty.
2786```roc
2787Set.is_empty(Set.empty({}) |> Set.insert(42))
2788
2789Set.is_empty(Set.empty({}))
2790```
2791
2792remove : Set k, k -> Set k
2793
2794Description:
2795Removes the value from the given `Set`.
2796```roc
2797numbers =
2798 Set.empty({})
2799 |> Set.insert(10)
2800 |> Set.insert(20)
2801 |> Set.remove(10)
2802
2803has10 = Set.contains(numbers, 10)
2804has20 = Set.contains(numbers, 20)
2805
2806expect has10 == Bool.false
2807expect has20 == Bool.true
2808```
2809
2810contains : Set k, k -> Bool
2811
2812Description:
2813Test if a value is in the `Set`.
2814```roc
2815Fruit : [Apple, Pear, Banana]
2816
2817fruit : Set Fruit
2818fruit =
2819 Set.single(Apple)
2820 |> Set.insert(Pear)
2821
2822has_apple = Set.contains(fruit, Apple)
2823has_banana = Set.contains(fruit, Banana)
2824
2825expect has_apple == Bool.true
2826expect has_banana == Bool.false
2827```
2828
2829to_list : Set k -> List k
2830
2831Description:
2832Retrieve the values in a `Set` as a `List`.
2833```roc
2834numbers : Set U64
2835numbers = Set.from_list([1,2,3,4,5])
2836
2837values = [1,2,3,4,5]
2838
2839expect Set.to_list(numbers) == values
2840```
2841
2842from_list : List k -> Set k
2843
2844Description:
2845Create a `Set` from a `List` of values.
2846```roc
2847values =
2848 Set.empty({})
2849 |> Set.insert(Banana)
2850 |> Set.insert(Apple)
2851 |> Set.insert(Pear)
2852
2853expect Set.from_list([Pear, Apple, Banana]) == values
2854```
2855
2856union : Set k, Set k -> Set k
2857
2858Description:
2859Combine two `Set` collection by keeping the
2860[union](https://en.wikipedia.org/wiki/Union_(set_theory))
2861of all the values pairs. This means that all of the values in both `Set`s
2862will be combined.
2863```roc
2864set1 = Set.single(Left)
2865set2 = Set.single(Right)
2866
2867expect Set.union(set1, set2) == Set.from_list([Left, Right])
2868```
2869
2870intersection : Set k, Set k -> Set k
2871
2872Description:
2873Combine two `Set`s by keeping the [intersection](https://en.wikipedia.org/wiki/Intersection_(set_theory))
2874of all the values pairs. This means that we keep only those values that are
2875in both `Set`s.
2876```roc
2877set1 = Set.from_list([Left, Other])
2878set2 = Set.from_list([Left, Right])
2879
2880expect Set.intersection(set1, set2) == Set.single(Left)
2881```
2882
2883difference : Set k, Set k -> Set k
2884
2885Description:
2886Remove the values in the first `Set` that are also in the second `Set`
2887using the [set difference](https://en.wikipedia.org/wiki/Complement_(set_theory)#Relative_complement)
2888of the values. This means that we will be left with only those values that
2889are in the first and not in the second.
2890```roc
2891first = Set.from_list([Left, Right, Up, Down])
2892second = Set.from_list([Left, Right])
2893
2894expect Set.difference(first, second) == Set.from_list([Up, Down])
2895```
2896
2897walk : Set k, state, (state, k -> state) -> state
2898
2899Description:
2900Iterate through the values of a given `Set` and build a value.
2901```roc
2902values = Set.from_list(["March", "April", "May"])
2903
2904starts_with_letter_m = \month ->
2905 when Str.to_utf8(month) is
2906 ['M', ..] -> Bool.true
2907 _ -> Bool.false
2908
2909reduce = \state, k ->
2910 if starts_with_letter_m(k) then
2911 state + 1
2912 else
2913 state
2914
2915result = Set.walk(values, 0, reduce)
2916
2917expect result == 2
2918```
2919
2920map : Set a, (a -> b) -> Set b
2921
2922Description:
2923Convert each value in the set to something new, by calling a conversion
2924function on each of them which receives the old value. Then return a
2925new set containing the converted values.
2926
2927join_map : Set a, (a -> Set b) -> Set b
2928
2929Description:
2930Like [Set.map], except the transformation function wraps the return value
2931in a set. At the end, all the sets get joined together
2932(using [Set.union]) into one set.
2933
2934You may know a similar function named `concat_map` in other languages.
2935
2936walk_until : Set k, state, (state, k -> [ Continue state, Break state ]) -> state
2937
2938Description:
2939Iterate through the values of a given `Set` and build a value, can stop
2940iterating part way through the collection.
2941```roc
2942numbers = Set.from_list([1,2,3,4,5,6,42,7,8,9,10])
2943
2944find42 = \state, k ->
2945 if k == 42 then
2946 Break(FoundTheAnswer)
2947 else
2948 Continue(state)
2949
2950result = Set.walk_until(numbers, NotFound, find42)
2951
2952expect result == FoundTheAnswer
2953```
2954
2955keep_if : Set k, (k -> Bool) -> Set k
2956
2957Description:
2958Run the given function on each element in the `Set`, and return
2959a `Set` with just the elements for which the function returned `Bool.true`.
2960```roc
2961expect Set.from_list([1,2,3,4,5])
2962 |> Set.keep_if(\k -> k >= 3)
2963 |> Bool.is_eq(Set.from_list([3,4,5]))
2964```
2965
2966drop_if : Set k, (k -> Bool) -> Set k
2967
2968Description:
2969Run the given function on each element in the `Set`, and return
2970a `Set` with just the elements for which the function returned `Bool.false`.
2971```roc
2972expect Set.from_list [1,2,3,4,5]
2973 |> Set.drop_if(\k -> k >= 3)
2974 |> Bool.is_eq(Set.from_list([1,2]))
2975```
2976
2977### Decode
2978
2979DecodeError : [TooShort]
2980
2981Description:
2982Error types when decoding a `List U8` of utf-8 bytes using a [Decoder]
2983
2984Description:
2985Return type of a [Decoder].
2986
2987This can be useful when creating a [custom](#custom) decoder or when
2988using [from_bytes_partial](#from_bytes_partial). For example writing unit tests,
2989such as;
2990```roc
2991expect
2992 input = "\"hello\", " |> Str.to_utf8
2993 actual = Decode.from_bytes_partial(input, Json.json)
2994 expected = Ok("hello")
2995
2996 actual.result == expected
2997```
2998
2999Description:
3000Decodes a `List U8` of utf-8 bytes where `val` is the type of the decoded
3001value, and `fmt` is a [Decoder] which implements the [DecoderFormatting]
3002ability
3003
3004Decoding : implements
3005 decoder : Decoder val fmt
3006 where val implements Decoding, fmt implements DecoderFormatting
3007
3008Description:
3009Definition of the [Decoding] ability
3010
3011DecoderFormatting : implements
3012 u8 : Decoder U8 fmt
3013 where fmt implements DecoderFormatting
3014 u16 : Decoder U16 fmt
3015 where fmt implements DecoderFormatting
3016 u32 : Decoder U32 fmt
3017 where fmt implements DecoderFormatting
3018 u64 : Decoder U64 fmt
3019 where fmt implements DecoderFormatting
3020 u128 : Decoder U128 fmt
3021 where fmt implements DecoderFormatting
3022 i8 : Decoder I8 fmt
3023 where fmt implements DecoderFormatting
3024 i16 : Decoder I16 fmt
3025 where fmt implements DecoderFormatting
3026 i32 : Decoder I32 fmt
3027 where fmt implements DecoderFormatting
3028 i64 : Decoder I64 fmt
3029 where fmt implements DecoderFormatting
3030 i128 : Decoder I128 fmt
3031 where fmt implements DecoderFormatting
3032 f32 : Decoder F32 fmt
3033 where fmt implements DecoderFormatting
3034 f64 : Decoder F64 fmt
3035 where fmt implements DecoderFormatting
3036 dec : Decoder Dec fmt
3037 where fmt implements DecoderFormatting
3038 bool : Decoder Bool fmt
3039 where fmt implements DecoderFormatting
3040 string : Decoder Str fmt
3041 where fmt implements DecoderFormatting
3042 list : Decoder elem fmt -> Decoder (List elem) fmt
3043 where fmt implements DecoderFormatting
3044 record :
3045 state,
3046 (state,
3047 Str
3048 ->
3049 [
3050 Keep (Decoder state fmt),
3051 Skip
3052 ]),
3053 (state, fmt -> Result val DecodeError)
3054 -> Decoder val fmt
3055 where fmt implements DecoderFormatting
3056 tuple :
3057 state,
3058 (state,
3059 U64
3060 ->
3061 [
3062 Next (Decoder state fmt),
3063 TooLong
3064 ]),
3065 (state -> Result val DecodeError)
3066 -> Decoder val fmt
3067 where fmt implements DecoderFormatting
3068
3069Description:
3070Definition of the [DecoderFormatting] ability
3071
3072custom : (List U8, fmt -> DecodeResult val) -> Decoder val fmt where fmt implements DecoderFormatting
3073
3074Description:
3075Build a custom [Decoder] function. For example the implementation of
3076`decode_bool` could be defined as follows;
3077
3078```roc
3079decode_bool = Decode.custom \bytes, @Json({}) ->
3080 when bytes is
3081 ['f', 'a', 'l', 's', 'e', ..] -> { result: Ok(Bool.false), rest: List.drop_first(bytes, 5) }
3082 ['t', 'r', 'u', 'e', ..] -> { result: Ok Bool.true, rest: List.drop_first(bytes, 4) }
3083 _ -> { result: Err(TooShort), rest: bytes }
3084```
3085
3086decode_with : List U8, Decoder val fmt, fmt -> DecodeResult val where fmt implements DecoderFormatting
3087
3088Description:
3089Decode a `List U8` utf-8 bytes using a specific [Decoder] function
3090
3091from_bytes_partial : List U8, fmt -> DecodeResult val where val implements Decoding, fmt implements DecoderFormatting
3092
3093Description:
3094Decode a `List U8` utf-8 bytes and return a [DecodeResult](#DecodeResult)
3095```roc
3096expect
3097 input = "\"hello\", " |> Str.to_utf8
3098 actual = Decode.from_bytes_partial(input Json.json)
3099 expected = Ok("hello")
3100
3101 actual.result == expected
3102```
3103
3104from_bytes : List U8, fmt -> Result val [Leftover (List U8)]DecodeError where val implements Decoding, fmt implements DecoderFormatting
3105
3106Description:
3107Decode a `List U8` utf-8 bytes and return a [Result] with no leftover bytes
3108expected. If successful returns `Ok val`, however, if there are bytes
3109remaining returns `Err Leftover (List U8)`.
3110```roc
3111expect
3112 input = "\"hello\", " |> Str.to_utf8
3113 actual = Decode.from_bytes(input, Json.json)
3114 expected = Ok("hello")
3115
3116 actual == expected
3117```
3118
3119map_result : DecodeResult a, (a -> b) -> DecodeResult b
3120
3121Description:
3122Transform the `val` of a [DecodeResult]
3123
3124### Encode
3125
3126Encoding : implements
3127 to_encoder : val -> Encoder fmt
3128 where val implements Encoding, fmt implements EncoderFormatting
3129
3130EncoderFormatting : implements
3131 u8 : U8 -> Encoder fmt
3132 where fmt implements EncoderFormatting
3133 u16 : U16 -> Encoder fmt
3134 where fmt implements EncoderFormatting
3135 u32 : U32 -> Encoder fmt
3136 where fmt implements EncoderFormatting
3137 u64 : U64 -> Encoder fmt
3138 where fmt implements EncoderFormatting
3139 u128 : U128 -> Encoder fmt
3140 where fmt implements EncoderFormatting
3141 i8 : I8 -> Encoder fmt
3142 where fmt implements EncoderFormatting
3143 i16 : I16 -> Encoder fmt
3144 where fmt implements EncoderFormatting
3145 i32 : I32 -> Encoder fmt
3146 where fmt implements EncoderFormatting
3147 i64 : I64 -> Encoder fmt
3148 where fmt implements EncoderFormatting
3149 i128 : I128 -> Encoder fmt
3150 where fmt implements EncoderFormatting
3151 f32 : F32 -> Encoder fmt
3152 where fmt implements EncoderFormatting
3153 f64 : F64 -> Encoder fmt
3154 where fmt implements EncoderFormatting
3155 dec : Dec -> Encoder fmt
3156 where fmt implements EncoderFormatting
3157 bool : Bool -> Encoder fmt
3158 where fmt implements EncoderFormatting
3159 string : Str -> Encoder fmt
3160 where fmt implements EncoderFormatting
3161 list : List elem, (elem -> Encoder fmt) -> Encoder fmt
3162 where fmt implements EncoderFormatting
3163 record : List
3164 {
3165 key : Str,
3166 value : Encoder fmt
3167 }
3168 -> Encoder fmt
3169 where fmt implements EncoderFormatting
3170 tuple : List (Encoder fmt) -> Encoder fmt
3171 where fmt implements EncoderFormatting
3172 tag : Str, List (Encoder fmt) -> Encoder fmt
3173 where fmt implements EncoderFormatting
3174
3175custom : (List U8, fmt -> List U8) -> Encoder fmt where fmt implements EncoderFormatting
3176
3177Description:
3178Creates a custom encoder from a given function.
3179
3180```roc
3181expect
3182 # Appends the byte 42
3183 custom_encoder = Encode.custom(\bytes, _fmt -> List.append(bytes, 42))
3184
3185 actual = Encode.append_with([], custom_encoder, Core.json)
3186 expected = [42] # Expected result is a list with a single byte, 42
3187
3188 actual == expected
3189```
3190
3191append_with : List U8, Encoder fmt, fmt -> List U8 where fmt implements EncoderFormatting
3192
3193append : List U8, val, fmt -> List U8 where val implements Encoding, fmt implements EncoderFormatting
3194
3195Description:
3196Appends the encoded representation of a value to an existing list of bytes.
3197
3198```roc
3199expect
3200 actual = Encode.append([], { foo: 43 }, Core.json)
3201 expected = Str.to_utf8("""{"foo":43}""")
3202
3203 actual == expected
3204```
3205
3206to_bytes : val, fmt -> List U8 where val implements Encoding, fmt implements EncoderFormatting
3207
3208Description:
3209Encodes a value to a list of bytes (`List U8`) according to the specified format.
3210
3211```roc
3212expect
3213 foo_rec = { foo: 42 }
3214
3215 actual = Encode.to_bytes(foo_rec, Core.json)
3216 expected = Str.to_utf8("""{"foo":42}""")
3217
3218 actual == expected
3219```
3220
3221### Hash
3222
3223Hash : implements
3224 hash : hasher, a -> hasher
3225 where a implements Hash, hasher implements Hasher
3226
3227Description:
3228A value that can be hashed.
3229
3230Hasher : implements
3231 add_bytes : a, List U8 -> a
3232 where a implements Hasher
3233 add_u8 : a, U8 -> a
3234 where a implements Hasher
3235 add_u16 : a, U16 -> a
3236 where a implements Hasher
3237 add_u32 : a, U32 -> a
3238 where a implements Hasher
3239 add_u64 : a, U64 -> a
3240 where a implements Hasher
3241 add_u128 : a, U128 -> a
3242 where a implements Hasher
3243 complete : a -> U64
3244 where a implements Hasher
3245
3246Description:
3247Describes a hashing algorithm that is fed bytes and produces an integer hash.
3248
3249The [Hasher] ability describes general-purpose hashers. It only allows
3250emission of 64-bit unsigned integer hashes. It is not suitable for
3251cryptographically-secure hashing.
3252
3253Description:
3254Adds a string into a [Hasher] by hashing its UTF-8 bytes.
3255
3256Description:
3257Adds a list of [Hash]able elements to a [Hasher] by hashing each element.
3258
3259hash_bool : a, Bool -> a where a implements Hasher
3260
3261Description:
3262Adds a single [Bool] to a hasher.
3263
3264hash_i8 : a, I8 -> a where a implements Hasher
3265
3266Description:
3267Adds a single I8 to a hasher.
3268
3269hash_i16 : a, I16 -> a where a implements Hasher
3270
3271Description:
3272Adds a single I16 to a hasher.
3273
3274hash_i32 : a, I32 -> a where a implements Hasher
3275
3276Description:
3277Adds a single I32 to a hasher.
3278
3279hash_i64 : a, I64 -> a where a implements Hasher
3280
3281Description:
3282Adds a single I64 to a hasher.
3283
3284hash_i128 : a, I128 -> a where a implements Hasher
3285
3286Description:
3287Adds a single I128 to a hasher.
3288
3289hash_dec : a, Dec -> a where a implements Hasher
3290
3291Description:
3292Adds a single [Dec] to a hasher.
3293
3294Description:
3295Adds a container of [Hash]able elements to a [Hasher] by hashing each element.
3296The container is iterated using the walk method passed in.
3297The order of the elements does not affect the final hash.
3298
3299### Box
3300
3301box : a -> Box a
3302
3303Description:
3304Allocates a value on the heap. Boxing is an expensive process as it copies
3305the value from the stack to the heap. This may provide a performance
3306optimization for advanced use cases with large values. A platform may require
3307that some values are boxed.
3308```roc
3309expect Box.unbox(Box.box("Stack Faster")) == "Stack Faster"
3310```
3311
3312unbox : Box a -> a
3313
3314Description:
3315Returns a boxed value.
3316```roc
3317expect Box.unbox(Box.box("Stack Faster") == "Stack Faster"
3318```
3319
3320### Inspect
3321
3322KeyValWalker : collection, state, (state, key, val -> state) -> state
3323
3324ElemWalker : collection, state, (state, elem -> state) -> state
3325
3326InspectFormatter : implements
3327 init : {} -> f
3328 where f implements InspectFormatter
3329 tag : Str, List (Inspector f) -> Inspector f
3330 where f implements InspectFormatter
3331 tuple : List (Inspector f) -> Inspector f
3332 where f implements InspectFormatter
3333 record : List
3334 {
3335 key : Str,
3336 value : Inspector f
3337 }
3338 -> Inspector f
3339 where f implements InspectFormatter
3340 bool : Bool -> Inspector f
3341 where f implements InspectFormatter
3342 str : Str -> Inspector f
3343 where f implements InspectFormatter
3344 list :
3345 list,
3346 ElemWalker state list elem,
3347 (elem -> Inspector f)
3348 -> Inspector f
3349 where f implements InspectFormatter
3350 set :
3351 set,
3352 ElemWalker state set elem,
3353 (elem -> Inspector f)
3354 -> Inspector f
3355 where f implements InspectFormatter
3356 dict :
3357 dict,
3358 KeyValWalker state dict key value,
3359 (key -> Inspector f),
3360 (value -> Inspector f)
3361 -> Inspector f
3362 where f implements InspectFormatter
3363 opaque : * -> Inspector f
3364 where f implements InspectFormatter
3365 function : * -> Inspector f
3366 where f implements InspectFormatter
3367 u8 : U8 -> Inspector f
3368 where f implements InspectFormatter
3369 i8 : I8 -> Inspector f
3370 where f implements InspectFormatter
3371 u16 : U16 -> Inspector f
3372 where f implements InspectFormatter
3373 i16 : I16 -> Inspector f
3374 where f implements InspectFormatter
3375 u32 : U32 -> Inspector f
3376 where f implements InspectFormatter
3377 i32 : I32 -> Inspector f
3378 where f implements InspectFormatter
3379 u64 : U64 -> Inspector f
3380 where f implements InspectFormatter
3381 i64 : I64 -> Inspector f
3382 where f implements InspectFormatter
3383 u128 : U128 -> Inspector f
3384 where f implements InspectFormatter
3385 i128 : I128 -> Inspector f
3386 where f implements InspectFormatter
3387 f32 : F32 -> Inspector f
3388 where f implements InspectFormatter
3389 f64 : F64 -> Inspector f
3390 where f implements InspectFormatter
3391 dec : Dec -> Inspector f
3392 where f implements InspectFormatter
3393
3394custom : (f -> f) -> Inspector f where f implements InspectFormatter
3395
3396apply : Inspector f, f -> f where f implements InspectFormatter
3397
3398Inspect : implements
3399 to_inspector : val -> Inspector f
3400 where val implements Inspect, f implements InspectFormatter
3401
3402inspect : val -> f where val implements Inspect, f implements InspectFormatter
3403
3404to_str : val -> Str where val implements Inspect
3405