1# LLM Docs
2
3## Compact Docs
4
5Copy just this section if you want to keep your context small.
6If you want all docs, check the section `Full Docs per Module` below.
7
8Str.Utf8Problem : [ InvalidStartByte, UnexpectedEndOfSequence, ExpectedContinuation, OverlongEncoding, CodepointTooLarge, EncodesSurrogateHalf ]
9Str.is_empty : Str -> Bool
10Str.concat : Str, Str -> Str
11Str.with_capacity : U64 -> Str
12Str.reserve : Str, U64 -> Str
13Str.join_with : List Str, Str -> Str
14Str.split_on : Str, Str -> List Str
15Str.repeat : Str, U64 -> Str
16Str.len : Str -> [LearnAboutStringsInRoc Str]
17Str.to_utf8 : Str -> List U8
18Str.from_utf8 : List U8 -> Result Str [ BadUtf8 { problem : Utf8Problem, index : U64 } ]
19Str.from_utf8_lossy : List U8 -> Str
20Str.from_utf16 : List U16 -> Result Str [ BadUtf16 { problem : Utf8Problem, index : U64 } ]
21Str.from_utf16_lossy : List U16 -> Str
22Str.from_utf32 : List U32 -> Result Str [ BadUtf32 { problem : Utf8Problem, index : U64 } ]
23Str.from_utf32_lossy : List U32 -> Str
24Str.starts_with : Str, Str -> Bool
25Str.ends_with : Str, Str -> Bool
26Str.trim : Str -> Str
27Str.trim_start : Str -> Str
28Str.trim_end : Str -> Str
29Str.to_dec : Str -> Result Dec [InvalidNumStr]
30Str.to_f64 : Str -> Result F64 [InvalidNumStr]
31Str.to_f32 : Str -> Result F32 [InvalidNumStr]
32Str.to_u128 : Str -> Result U128 [InvalidNumStr]
33Str.to_i128 : Str -> Result I128 [InvalidNumStr]
34Str.to_u64 : Str -> Result U64 [InvalidNumStr]
35Str.to_i64 : Str -> Result I64 [InvalidNumStr]
36Str.to_u32 : Str -> Result U32 [InvalidNumStr]
37Str.to_i32 : Str -> Result I32 [InvalidNumStr]
38Str.to_u16 : Str -> Result U16 [InvalidNumStr]
39Str.to_i16 : Str -> Result I16 [InvalidNumStr]
40Str.to_u8 : Str -> Result U8 [InvalidNumStr]
41Str.to_i8 : Str -> Result I8 [InvalidNumStr]
42Str.count_utf8_bytes : Str -> U64
43Str.replace_each : Str, Str, Str -> Str
44Str.replace_first : Str, Str, Str -> Str
45Str.replace_last : Str, Str, Str -> Str
46Str.split_first : Str, Str -> Result { before : Str, after : Str } [NotFound]
47Str.split_last : Str, Str -> Result { before : Str, after : Str } [NotFound]
48Str.walk_utf8_with_index : Str, state, (state, U8, U64 -> state) -> state
49Str.walk_utf8 : Str, state, (state, U8 -> state) -> state
50Str.release_excess_capacity : Str -> Str
51Str.with_prefix : Str, Str -> Str
52Str.contains : Str, Str -> Bool
53Str.drop_prefix : Str, Str -> Str
54Str.drop_suffix : Str, Str -> Str
55Str.with_ascii_lowercased : Str -> Str
56Str.with_ascii_uppercased : Str -> Str
57Str.caseless_ascii_equals : Str, Str -> Bool
58Num.e : Frac *
59Num.pi : Frac *
60Num.tau : Frac *
61Num.to_str : Num * -> Str
62Num.int_cast : Int a -> Int b
63Num.compare : Num a, Num a -> [ LT, EQ, GT ]
64Num.is_lt : Num a, Num a -> Bool
65Num.is_gt : Num a, Num a -> Bool
66Num.is_lte : Num a, Num a -> Bool
67Num.is_gte : Num a, Num a -> Bool
68Num.is_approx_eq : Frac a, Frac a, { rtol ? Frac a, atol ? Frac a } -> Bool
69Num.is_zero : Num a -> Bool
70Num.is_even : Int a -> Bool
71Num.is_odd : Int a -> Bool
72Num.is_positive : Num a -> Bool
73Num.is_negative : Num a -> Bool
74Num.to_frac : Num * -> Frac *
75Num.is_nan : Frac * -> Bool
76Num.is_infinite : Frac * -> Bool
77Num.is_finite : Frac * -> Bool
78Num.abs : Num a -> Num a
79Num.abs_diff : Num a, Num a -> Num a
80Num.neg : Num a -> Num a
81Num.add : Num a, Num a -> Num a
82Num.sub : Num a, Num a -> Num a
83Num.mul : Num a, Num a -> Num a
84Num.min : Num a, Num a -> Num a
85Num.max : Num a, Num a -> Num a
86Num.sin : Frac a -> Frac a
87Num.cos : Frac a -> Frac a
88Num.tan : Frac a -> Frac a
89Num.asin : Frac a -> Frac a
90Num.acos : Frac a -> Frac a
91Num.atan : Frac a -> Frac a
92Num.sqrt : Frac a -> Frac a
93Num.sqrt_checked : Frac a -> Result (Frac a) [SqrtOfNegative]
94Num.log : Frac a -> Frac a
95Num.log_checked : Frac a -> Result (Frac a) [LogNeedsPositive]
96Num.div : Frac a, Frac a -> Frac a
97Num.div_checked : Frac a, Frac a -> Result (Frac a) [DivByZero]
98Num.div_ceil : Int a, Int a -> Int a
99Num.div_ceil_checked : Int a, Int a -> Result (Int a) [DivByZero]
100Num.div_trunc : Int a, Int a -> Int a
101Num.div_trunc_checked : Int a, Int a -> Result (Int a) [DivByZero]
102Num.rem : Int a, Int a -> Int a
103Num.rem_checked : Int a, Int a -> Result (Int a) [DivByZero]
104Num.is_multiple_of : Int a, Int a -> Bool
105Num.bitwise_and : Int a, Int a -> Int a
106Num.bitwise_xor : Int a, Int a -> Int a
107Num.bitwise_or : Int a, Int a -> Int a
108Num.bitwise_not : Int a -> Int a
109Num.shift_left_by : Int a, U8 -> Int a
110Num.shift_right_by : Int a, U8 -> Int a
111Num.shift_right_zf_by : Int a, U8 -> Int a
112Num.round : Frac * -> Int *
113Num.floor : Frac * -> Int *
114Num.ceiling : Frac * -> Int *
115Num.pow : Frac a, Frac a -> Frac a
116Num.pow_int : Int a, Int a -> Int a
117Num.count_leading_zero_bits : Int a -> U8
118Num.count_trailing_zero_bits : Int a -> U8
119Num.count_one_bits : Int a -> U8
120Num.add_wrap : Int range, Int range -> Int range
121Num.add_saturated : Num a, Num a -> Num a
122Num.add_checked : Num a, Num a -> Result (Num a) [Overflow]
123Num.sub_wrap : Int range, Int range -> Int range
124Num.sub_saturated : Num a, Num a -> Num a
125Num.sub_checked : Num a, Num a -> Result (Num a) [Overflow]
126Num.mul_wrap : Int range, Int range -> Int range
127Num.mul_saturated : Num a, Num a -> Num a
128Num.mul_checked : Num a, Num a -> Result (Num a) [Overflow]
129Num.min_i8 : I8
130Num.max_i8 : I8
131Num.min_u8 : U8
132Num.max_u8 : U8
133Num.min_i16 : I16
134Num.max_i16 : I16
135Num.min_u16 : U16
136Num.max_u16 : U16
137Num.min_i32 : I32
138Num.max_i32 : I32
139Num.min_u32 : U32
140Num.max_u32 : U32
141Num.min_i64 : I64
142Num.max_i64 : I64
143Num.min_u64 : U64
144Num.max_u64 : U64
145Num.min_i128 : I128
146Num.max_i128 : I128
147Num.min_u128 : U128
148Num.max_u128 : U128
149Num.min_f32 : F32
150Num.max_f32 : F32
151Num.min_f64 : F64
152Num.max_f64 : F64
153Num.to_i8 : Int * -> I8
154Num.to_i16 : Int * -> I16
155Num.to_i32 : Int * -> I32
156Num.to_i64 : Int * -> I64
157Num.to_i128 : Int * -> I128
158Num.to_u8 : Int * -> U8
159Num.to_u16 : Int * -> U16
160Num.to_u32 : Int * -> U32
161Num.to_u64 : Int * -> U64
162Num.to_u128 : Int * -> U128
163Num.to_f32 : Num * -> F32
164Num.to_f64 : Num * -> F64
165Num.to_i8_checked : Int * -> Result I8 [OutOfBounds]
166Num.to_i16_checked : Int * -> Result I16 [OutOfBounds]
167Num.to_i32_checked : Int * -> Result I32 [OutOfBounds]
168Num.to_i64_checked : Int * -> Result I64 [OutOfBounds]
169Num.to_i128_checked : Int * -> Result I128 [OutOfBounds]
170Num.to_u8_checked : Int * -> Result U8 [OutOfBounds]
171Num.to_u16_checked : Int * -> Result U16 [OutOfBounds]
172Num.to_u32_checked : Int * -> Result U32 [OutOfBounds]
173Num.to_u64_checked : Int * -> Result U64 [OutOfBounds]
174Num.to_u128_checked : Int * -> Result U128 [OutOfBounds]
175Num.to_f32_checked : Num * -> Result F32 [OutOfBounds]
176Num.to_f64_checked : Num * -> Result F64 [OutOfBounds]
177Num.without_decimal_point : Dec -> I128
178Num.with_decimal_point : I128 -> Dec
179Num.f32_to_parts : F32 -> { sign : Bool, exponent : U8, fraction : U32 }
180Num.f64_to_parts : F64 -> { sign : Bool, exponent : U16, fraction : U64 }
181Num.f32_from_parts : { sign : Bool, exponent : U8, fraction : U32 } -> F32
182Num.f64_from_parts : { sign : Bool, exponent : U16, fraction : U64 } -> F64
183Num.f32_to_bits : F32 -> U32
184Num.f64_to_bits : F64 -> U64
185Num.dec_to_bits : Dec -> U128
186Num.f32_from_bits : U32 -> F32
187Num.f64_from_bits : U64 -> F64
188Num.dec_from_bits : U128 -> Dec
189Num.from_bool : Bool -> Num *
190Num.nan_f32 : F32
191Num.nan_f64 : F64
192Num.infinity_f32 : F32
193Num.infinity_f64 : F64
194Bool.Eq : implements
195 is_eq : a, a -> Bool
196 where a implements Eq
197Bool.true : Bool
198Bool.false : Bool
199Bool.not : Bool -> Bool
200Bool.is_not_eq : a, a -> Bool where a implements Eq
201Result.Result : [ Ok ok, Err err ]
202Result.is_ok : Result ok err -> Bool
203Result.is_err : Result ok err -> Bool
204Result.with_default : Result ok err, ok -> ok
205Result.map_ok : Result a err, (a -> b) -> Result b err
206Result.map_err : Result ok a, (a -> b) -> Result ok b
207Result.on_err : Result a err, (err -> Result a other_err) -> Result a other_err
208Result.on_err! : Result a err, (err => Result a other_err) => Result a other_err
209Result.map_both : Result ok1 err1, (ok1 -> ok2), (err1 -> err2) -> Result ok2 err2
210Result.map2 : Result a err, Result b err, (a, b -> c) -> Result c err
211Result.try : Result a err, (a -> Result b err) -> Result b err
212List.is_empty : List * -> Bool
213List.get : List a, U64 -> Result a [OutOfBounds]
214List.replace : List a, U64, a -> { list : List a, value : a }
215List.set : List a, U64, a -> List a
216List.update : List a, U64, (a -> a) -> List a
217List.append : List a, a -> List a
218List.append_if_ok : List a, Result a * -> List a
219List.prepend : List a, a -> List a
220List.prepend_if_ok : List a, Result a * -> List a
221List.len : List * -> U64
222List.with_capacity : U64 -> List *
223List.reserve : List a, U64 -> List a
224List.release_excess_capacity : List a -> List a
225List.concat : List a, List a -> List a
226List.last : List a -> Result a [ListWasEmpty]
227List.single : a -> List a
228List.repeat : a, U64 -> List a
229List.reverse : List a -> List a
230List.join : List (List a) -> List a
231List.contains : List a, a -> Bool where a implements Eq
232List.walk : List elem, state, (state, elem -> state) -> state
233List.walk_with_index : List elem, state, (state, elem, U64 -> state) -> state
234List.walk_with_index_until : List elem, state, (state, elem, U64 -> [ Continue state, Break state ]) -> state
235List.walk_backwards : List elem, state, (state, elem -> state) -> state
236List.walk_until : List elem, state, (state, elem -> [ Continue state, Break state ]) -> state
237List.walk_backwards_until : List elem, state, (state, elem -> [ Continue state, Break state ]) -> state
238List.walk_from : List elem, U64, state, (state, elem -> state) -> state
239List.walk_from_until : List elem, U64, state, (state, elem -> [ Continue state, Break state ]) -> state
240List.sum : List (Num a) -> Num a
241List.product : List (Num a) -> Num a
242List.any : List a, (a -> Bool) -> Bool
243List.all : List a, (a -> Bool) -> Bool
244List.keep_if : List a, (a -> Bool) -> List a
245List.keep_if_try! : List a, (a => Result Bool err) => Result (List a) err
246List.drop_if : List a, (a -> Bool) -> List a
247List.count_if : List a, (a -> Bool) -> U64
248List.keep_oks : List before, (before -> Result after *) -> List after
249List.keep_errs : List before, (before -> Result * after) -> List after
250List.map : List a, (a -> b) -> List b
251List.map2 : List a, List b, (a, b -> c) -> List c
252List.map3 : List a, List b, List c, (a, b, c -> d) -> List d
253List.map4 : List a, List b, List c, List d, (a, b, c, d -> e) -> List e
254List.map_with_index : List a, (a, U64 -> b) -> List b
255List.sort_with : List a, (a, a -> [ LT, EQ, GT ]) -> List a
256List.sort_asc : List (Num a) -> List (Num a)
257List.sort_desc : List (Num a) -> List (Num a)
258List.swap : List a, U64, U64 -> List a
259List.first : List a -> Result a [ListWasEmpty]
260List.take_first : List elem, U64 -> List elem
261List.take_last : List elem, U64 -> List elem
262List.drop_first : List elem, U64 -> List elem
263List.drop_last : List elem, U64 -> List elem
264List.drop_at : List elem, U64 -> List elem
265List.min : List (Num a) -> Result (Num a) [ListWasEmpty]
266List.max : List (Num a) -> Result (Num a) [ListWasEmpty]
267List.join_map : List a, (a -> List b) -> List b
268List.find_first : List elem, (elem -> Bool) -> Result elem [NotFound]
269List.find_last : List elem, (elem -> Bool) -> Result elem [NotFound]
270List.find_first_index : List elem, (elem -> Bool) -> Result U64 [NotFound]
271List.find_last_index : List elem, (elem -> Bool) -> Result U64 [NotFound]
272List.sublist : List elem, { start : U64, len : U64 } -> List elem
273List.intersperse : List elem, elem -> List elem
274List.starts_with : List elem, List elem -> Bool where elem implements Eq
275List.ends_with : List elem, List elem -> Bool where elem implements Eq
276List.split_at : List elem, U64 -> { before : List elem, others : List elem }
277List.split_on : List a, a -> List (List a) where a implements Eq
278List.split_on_list : List a, List a -> List (List a) where a implements Eq
279List.split_first : List elem, elem -> Result { before : List elem, after : List elem } [NotFound] where elem implements Eq
280List.split_last : List elem, elem -> Result { before : List elem, after : List elem } [NotFound] where elem implements Eq
281List.chunks_of : List a, U64 -> List (List a)
282List.map_try : List elem, (elem -> Result ok err) -> Result (List ok) err
283List.map_try! : List elem, (elem => Result ok err) => Result (List ok) err
284List.walk_try : List elem, state, (state, elem -> Result state err) -> Result state err
285List.concat_utf8 : List U8, Str -> List U8
286List.for_each! : List a, (a => {}) => {}
287List.for_each_try! : List a, (a => Result {} err) => Result {} err
288List.walk! : List elem, state, (state, elem => state) => state
289List.walk_try! : List elem, state, (state, elem => Result state err) => Result state err
290Dict.empty : {} -> Dict * *
291Dict.with_capacity : U64 -> Dict * *
292Dict.reserve : Dict k v, U64 -> Dict k v
293Dict.release_excess_capacity : Dict k v -> Dict k v
294Dict.capacity : Dict * * -> U64
295Dict.single : k, v -> Dict k v
296Dict.from_list : List ( k, v ) -> Dict k v
297Dict.len : Dict * * -> U64
298Dict.is_empty : Dict * * -> Bool
299Dict.clear : Dict k v -> Dict k v
300Dict.map : Dict k a, (k, a -> b) -> Dict k b
301Dict.join_map : Dict a b, (a, b -> Dict x y) -> Dict x y
302Dict.walk : Dict k v, state, (state, k, v -> state) -> state
303Dict.walk_until : Dict k v, state, (state, k, v -> [ Continue state, Break state ]) -> state
304Dict.keep_if : Dict k v, ( ( k, v ) -> Bool) -> Dict k v
305Dict.drop_if : Dict k v, ( ( k, v ) -> Bool) -> Dict k v
306Dict.get : Dict k v, k -> Result v [KeyNotFound]
307Dict.contains : Dict k v, k -> Bool
308Dict.insert : Dict k v, k, v -> Dict k v
309Dict.remove : Dict k v, k -> Dict k v
310Dict.update : Dict k v, k, (Result v [Missing] -> Result v [Missing]) -> Dict k v
311Dict.to_list : Dict k v -> List ( k, v )
312Dict.keys : Dict k v -> List k
313Dict.values : Dict k v -> List v
314Dict.insert_all : Dict k v, Dict k v -> Dict k v
315Dict.keep_shared : Dict k v, Dict k v -> Dict k v where v implements Eq
316Dict.remove_all : Dict k v, Dict k v -> Dict k v
317Set.empty : {} -> Set *
318Set.with_capacity : U64 -> Set *
319Set.reserve : Set k, U64 -> Set k
320Set.release_excess_capacity : Set k -> Set k
321Set.single : k -> Set k
322Set.insert : Set k, k -> Set k
323Set.len : Set * -> U64
324Set.capacity : Set * -> U64
325Set.is_empty : Set * -> Bool
326Set.remove : Set k, k -> Set k
327Set.contains : Set k, k -> Bool
328Set.to_list : Set k -> List k
329Set.from_list : List k -> Set k
330Set.union : Set k, Set k -> Set k
331Set.intersection : Set k, Set k -> Set k
332Set.difference : Set k, Set k -> Set k
333Set.walk : Set k, state, (state, k -> state) -> state
334Set.map : Set a, (a -> b) -> Set b
335Set.join_map : Set a, (a -> Set b) -> Set b
336Set.walk_until : Set k, state, (state, k -> [ Continue state, Break state ]) -> state
337Set.keep_if : Set k, (k -> Bool) -> Set k
338Set.drop_if : Set k, (k -> Bool) -> Set k
339Decode.DecodeError : [TooShort]
340Decode.Decoding : implements
341 decoder : Decoder val fmt
342 where val implements Decoding, fmt implements DecoderFormatting
343Decode.DecoderFormatting : implements
344 u8 : Decoder U8 fmt
345 where fmt implements DecoderFormatting
346 u16 : Decoder U16 fmt
347 where fmt implements DecoderFormatting
348 u32 : Decoder U32 fmt
349 where fmt implements DecoderFormatting
350 u64 : Decoder U64 fmt
351 where fmt implements DecoderFormatting
352 u128 : Decoder U128 fmt
353 where fmt implements DecoderFormatting
354 i8 : Decoder I8 fmt
355 where fmt implements DecoderFormatting
356 i16 : Decoder I16 fmt
357 where fmt implements DecoderFormatting
358 i32 : Decoder I32 fmt
359 where fmt implements DecoderFormatting
360 i64 : Decoder I64 fmt
361 where fmt implements DecoderFormatting
362 i128 : Decoder I128 fmt
363 where fmt implements DecoderFormatting
364 f32 : Decoder F32 fmt
365 where fmt implements DecoderFormatting
366 f64 : Decoder F64 fmt
367 where fmt implements DecoderFormatting
368 dec : Decoder Dec fmt
369 where fmt implements DecoderFormatting
370 bool : Decoder Bool fmt
371 where fmt implements DecoderFormatting
372 string : Decoder Str fmt
373 where fmt implements DecoderFormatting
374 list : Decoder elem fmt -> Decoder (List elem) fmt
375 where fmt implements DecoderFormatting
376 record :
377 state,
378 (state,
379 Str
380 ->
381 [
382 Keep (Decoder state fmt),
383 Skip
384 ]),
385 (state, fmt -> Result val DecodeError)
386 -> Decoder val fmt
387 where fmt implements DecoderFormatting
388 tuple :
389 state,
390 (state,
391 U64
392 ->
393 [
394 Next (Decoder state fmt),
395 TooLong
396 ]),
397 (state -> Result val DecodeError)
398 -> Decoder val fmt
399 where fmt implements DecoderFormatting
400Decode.custom : (List U8, fmt -> DecodeResult val) -> Decoder val fmt where fmt implements DecoderFormatting
401Decode.decode_with : List U8, Decoder val fmt, fmt -> DecodeResult val where fmt implements DecoderFormatting
402Decode.from_bytes_partial : List U8, fmt -> DecodeResult val where val implements Decoding, fmt implements DecoderFormatting
403Decode.from_bytes : List U8, fmt -> Result val [Leftover (List U8)]DecodeError where val implements Decoding, fmt implements DecoderFormatting
404Decode.map_result : DecodeResult a, (a -> b) -> DecodeResult b
405Encode.Encoding : implements
406 to_encoder : val -> Encoder fmt
407 where val implements Encoding, fmt implements EncoderFormatting
408Encode.EncoderFormatting : implements
409 u8 : U8 -> Encoder fmt
410 where fmt implements EncoderFormatting
411 u16 : U16 -> Encoder fmt
412 where fmt implements EncoderFormatting
413 u32 : U32 -> Encoder fmt
414 where fmt implements EncoderFormatting
415 u64 : U64 -> Encoder fmt
416 where fmt implements EncoderFormatting
417 u128 : U128 -> Encoder fmt
418 where fmt implements EncoderFormatting
419 i8 : I8 -> Encoder fmt
420 where fmt implements EncoderFormatting
421 i16 : I16 -> Encoder fmt
422 where fmt implements EncoderFormatting
423 i32 : I32 -> Encoder fmt
424 where fmt implements EncoderFormatting
425 i64 : I64 -> Encoder fmt
426 where fmt implements EncoderFormatting
427 i128 : I128 -> Encoder fmt
428 where fmt implements EncoderFormatting
429 f32 : F32 -> Encoder fmt
430 where fmt implements EncoderFormatting
431 f64 : F64 -> Encoder fmt
432 where fmt implements EncoderFormatting
433 dec : Dec -> Encoder fmt
434 where fmt implements EncoderFormatting
435 bool : Bool -> Encoder fmt
436 where fmt implements EncoderFormatting
437 string : Str -> Encoder fmt
438 where fmt implements EncoderFormatting
439 list : List elem, (elem -> Encoder fmt) -> Encoder fmt
440 where fmt implements EncoderFormatting
441 record : List
442 {
443 key : Str,
444 value : Encoder fmt
445 }
446 -> Encoder fmt
447 where fmt implements EncoderFormatting
448 tuple : List (Encoder fmt) -> Encoder fmt
449 where fmt implements EncoderFormatting
450 tag : Str, List (Encoder fmt) -> Encoder fmt
451 where fmt implements EncoderFormatting
452Encode.custom : (List U8, fmt -> List U8) -> Encoder fmt where fmt implements EncoderFormatting
453Encode.append_with : List U8, Encoder fmt, fmt -> List U8 where fmt implements EncoderFormatting
454Encode.append : List U8, val, fmt -> List U8 where val implements Encoding, fmt implements EncoderFormatting
455Encode.to_bytes : val, fmt -> List U8 where val implements Encoding, fmt implements EncoderFormatting
456Hash.Hash : implements
457 hash : hasher, a -> hasher
458 where a implements Hash, hasher implements Hasher
459Hash.Hasher : implements
460 add_bytes : a, List U8 -> a
461 where a implements Hasher
462 add_u8 : a, U8 -> a
463 where a implements Hasher
464 add_u16 : a, U16 -> a
465 where a implements Hasher
466 add_u32 : a, U32 -> a
467 where a implements Hasher
468 add_u64 : a, U64 -> a
469 where a implements Hasher
470 add_u128 : a, U128 -> a
471 where a implements Hasher
472 complete : a -> U64
473 where a implements Hasher
474Hash.hash_bool : a, Bool -> a where a implements Hasher
475Hash.hash_i8 : a, I8 -> a where a implements Hasher
476Hash.hash_i16 : a, I16 -> a where a implements Hasher
477Hash.hash_i32 : a, I32 -> a where a implements Hasher
478Hash.hash_i64 : a, I64 -> a where a implements Hasher
479Hash.hash_i128 : a, I128 -> a where a implements Hasher
480Hash.hash_dec : a, Dec -> a where a implements Hasher
481Box.box : a -> Box a
482Box.unbox : Box a -> a
483Inspect.KeyValWalker : collection, state, (state, key, val -> state) -> state
484Inspect.ElemWalker : collection, state, (state, elem -> state) -> state
485Inspect.InspectFormatter : implements
486 init : {} -> f
487 where f implements InspectFormatter
488 tag : Str, List (Inspector f) -> Inspector f
489 where f implements InspectFormatter
490 tuple : List (Inspector f) -> Inspector f
491 where f implements InspectFormatter
492 record : List
493 {
494 key : Str,
495 value : Inspector f
496 }
497 -> Inspector f
498 where f implements InspectFormatter
499 bool : Bool -> Inspector f
500 where f implements InspectFormatter
501 str : Str -> Inspector f
502 where f implements InspectFormatter
503 list :
504 list,
505 ElemWalker state list elem,
506 (elem -> Inspector f)
507 -> Inspector f
508 where f implements InspectFormatter
509 set :
510 set,
511 ElemWalker state set elem,
512 (elem -> Inspector f)
513 -> Inspector f
514 where f implements InspectFormatter
515 dict :
516 dict,
517 KeyValWalker state dict key value,
518 (key -> Inspector f),
519 (value -> Inspector f)
520 -> Inspector f
521 where f implements InspectFormatter
522 opaque : * -> Inspector f
523 where f implements InspectFormatter
524 function : * -> Inspector f
525 where f implements InspectFormatter
526 u8 : U8 -> Inspector f
527 where f implements InspectFormatter
528 i8 : I8 -> Inspector f
529 where f implements InspectFormatter
530 u16 : U16 -> Inspector f
531 where f implements InspectFormatter
532 i16 : I16 -> Inspector f
533 where f implements InspectFormatter
534 u32 : U32 -> Inspector f
535 where f implements InspectFormatter
536 i32 : I32 -> Inspector f
537 where f implements InspectFormatter
538 u64 : U64 -> Inspector f
539 where f implements InspectFormatter
540 i64 : I64 -> Inspector f
541 where f implements InspectFormatter
542 u128 : U128 -> Inspector f
543 where f implements InspectFormatter
544 i128 : I128 -> Inspector f
545 where f implements InspectFormatter
546 f32 : F32 -> Inspector f
547 where f implements InspectFormatter
548 f64 : F64 -> Inspector f
549 where f implements InspectFormatter
550 dec : Dec -> Inspector f
551 where f implements InspectFormatter
552Inspect.custom : (f -> f) -> Inspector f where f implements InspectFormatter
553Inspect.apply : Inspector f, f -> f where f implements InspectFormatter
554Inspect.Inspect : implements
555 to_inspector : val -> Inspector f
556 where val implements Inspect, f implements InspectFormatter
557Inspect.inspect : val -> f where val implements Inspect, f implements InspectFormatter
558Inspect.to_str : val -> Str where val implements Inspect
559
560## Full Docs per Module
561### Str
562
563Utf8Problem : [ InvalidStartByte, UnexpectedEndOfSequence, ExpectedContinuation, OverlongEncoding, CodepointTooLarge, EncodesSurrogateHalf ]
564
565is_empty : Str -> Bool
566
567Description:
568Returns [Bool.true] if the string is empty, and [Bool.false] otherwise.
569```roc
570expect Str.is_empty("hi!") == Bool.false
571expect Str.is_empty("") == Bool.true
572```
573
574concat : Str, Str -> Str
575
576Description:
577Concatenates two strings together.
578```roc
579expect Str.concat("ab", "cd") == "abcd"
580expect Str.concat("hello", "") == "hello"
581expect Str.concat("", "") == ""
582```
583
584with_capacity : U64 -> Str
585
586Description:
587Returns a string of the specified capacity without any content.
588
589This is a performance optimization tool that's like calling [Str.reserve] on an empty string.
590It's useful when you plan to build up a string incrementally, for example by calling [Str.concat] on it:
591
592```roc
593greeting = "Hello and welcome to Roc"
594subject = "Awesome Programmer"
595
596# Evaluates to "Hello and welcome to Roc, Awesome Programmer!"
597hello_world =
598 Str.with_capacity(45)
599 |> Str.concat(greeting)
600 |> Str.concat(", ")
601 |> Str.concat(subject)
602 |> Str.concat("!")
603```
604
605In general, if you plan to use [Str.concat] on an empty string, it will be faster to start with
606[Str.with_capacity] than with `""`. Even if you don't know the exact capacity of the string, giving [with_capacity]
607a higher value than ends up being necessary can help prevent reallocation and copying—at
608the cost of using more memory than is necessary.
609
610For more details on how the performance optimization works, see [Str.reserve].
611
612reserve : Str, U64 -> Str
613
614Description:
615Increase a string's capacity by at least the given number of additional bytes.
616
617This can improve the performance of string concatenation operations like [Str.concat] by
618allocating extra capacity up front, which can prevent the need for reallocations and copies.
619Consider the following example which does not use [Str.reserve]:
620
621```roc
622greeting = "Hello and welcome to Roc"
623subject = "Awesome Programmer"
624
625# Evaluates to "Hello and welcome to Roc, Awesome Programmer!"
626hello_world =
627 greeting
628 |> Str.concat(", ")
629 |> Str.concat(subject)
630 |> Str.concat("!")
631```
632
633In this example:
6341. We start with `greeting`, which has both a length and capacity of 24 (bytes).
6352. `|> Str.concat ", "` will see that there isn't enough capacity to add 2 more bytes for the `", "`, so it will create a new heap allocation with enough bytes to hold both. (This probably will be more than 7 bytes, because when [Str] functions reallocate, they apply a multiplier to the exact capacity required. This makes it less likely that future realloctions will be needed. The multiplier amount is not specified, because it may change in future releases of Roc, but it will likely be around 1.5 to 2 times the exact capacity required.) Then it will copy the current bytes (`"Hello"`) into the new allocation, and finally concatenate the `", "` into the new allocation. The old allocation will then be deallocated because it's no longer referenced anywhere in the program.
6363. `|> Str.concat subject` will again check if there is enough capacity in the string. If it doesn't find enough capacity once again, it will make a third allocation, copy the existing bytes (`"Hello, "`) into that third allocation, and then deallocate the second allocation because it's already no longer being referenced anywhere else in the program. (It may find enough capacity in this particular case, because the previous [Str.concat] allocated something like 1.5 to 2 times the necessary capacity in order to anticipate future concatenations like this...but if something longer than `"World"` were being concatenated here, it might still require further reallocation and copying.)
6374. `|> Str.concat "!\n"` will repeat this process once more.
638
639This process can have significant performance costs due to multiple reallocation of new strings, copying between old strings and new strings, and deallocation of immediately obsolete strings.
640
641Here's a modified example which uses [Str.reserve] to eliminate the need for all that reallocation, copying, and deallocation.
642
643```roc
644hello_world =
645 greeting
646 |> Str.reserve(21)
647 |> Str.concat(", ")
648 |> Str.concat(subject)
649 |> Str.concat("!")
650```
651
652In this example:
6531. We again start with `greeting`, which has both a length and capacity of 24 bytes.
6542. `|> Str.reserve(21)` will ensure that there is enough capacity in the string for an additional 21 bytes (to make room for `", "`, `"Awesome Programmer"`, and `"!"`). Since the current capacity is only 24, it will create a new 45-byte (24 + 21) heap allocation and copy the contents of the existing allocation (`greeting`) into it.
6553. `|> Str.concat(", ")` will concatenate `, ` to the string. No reallocation, copying, or deallocation will be necessary, because the string already has a capacity of 45 btytes, and `greeting` will only use 24 of them.
6564. `|> Str.concat(subject)` will concatenate `subject` (`"Awesome Programmer"`) to the string. Again, no reallocation, copying, or deallocation will be necessary.
6575. `|> Str.concat "!\n"` will concatenate `"!\n"` to the string, still without any reallocation, copying, or deallocation.
658
659Here, [Str.reserve] prevented multiple reallocations, copies, and deallocations during the
660[Str.concat] calls. Notice that it did perform a heap allocation before any [Str.concat] calls
661were made, which means that using [Str.reserve] is not free! You should only use it if you actually
662expect to make use of the extra capacity.
663
664Ideally, you'd be able to predict exactly how many extra bytes of capacity will be needed, but this
665may not always be knowable. When you don't know exactly how many bytes to reserve, you can often get better
666performance by choosing a number of bytes that's too high, because a number that's too low could lead to reallocations. There's a limit to
667this, of course; if you always give it ten times what it turns out to need, that could prevent
668reallocations but will also waste a lot of memory!
669
670If you plan to use [Str.reserve] on an empty string, it's generally better to use [Str.with_capacity] instead.
671
672join_with : List Str, Str -> Str
673
674Description:
675Combines a [List] of strings into a single string, with a separator
676string in between each.
677```roc
678expect Str.join_with(["one", "two", "three"], ", ") == "one, two, three"
679expect Str.join_with(["1", "2", "3", "4"], ".") == "1.2.3.4"
680```
681
682split_on : Str, Str -> List Str
683
684Description:
685Split a string around a separator.
686
687Passing `""` for the separator is not useful;
688it returns the original string wrapped in a [List].
689```roc
690expect Str.split_on("1,2,3", ",") == ["1","2","3"]
691expect Str.split_on("1,2,3", "") == ["1,2,3"]
692```
693
694repeat : Str, U64 -> Str
695
696Description:
697Repeats a string the given number of times.
698```roc
699expect Str.repeat("z", 3) == "zzz"
700expect Str.repeat("na", 8) == "nananananananana"
701```
702Returns `""` when given `""` for the string or `0` for the count.
703```roc
704expect Str.repeat("", 10) == ""
705expect Str.repeat("anything", 0) == ""
706```
707
708len : Str -> [LearnAboutStringsInRoc Str]
709
710Description:
711A stub function to help people discover [how they should handle this in Roc](https://www.roc-lang.org/faq.html#strings-in-roc).
712
713to_utf8 : Str -> List U8
714
715Description:
716Returns a [List] of the string's [U8] UTF-8 [code units](https://unicode.org/glossary/#code_unit).
717(To split the string into a [List] of smaller [Str] values instead of [U8] values,
718see [Str.split_on].)
719```roc
720expect Str.to_utf8("Roc") == [82, 111, 99]
721expect Str.to_utf8("鹏") == [233, 185, 143]
722expect Str.to_utf8("சி") == [224, 174, 154, 224, 174, 191]
723expect Str.to_utf8("🐦") == [240, 159, 144, 166]
724```
725
726from_utf8 : List U8 -> Result Str [ BadUtf8 { problem : Utf8Problem, index : U64 } ]
727
728Description:
729Converts a [List] of [U8] UTF-8 [code units](https://unicode.org/glossary/#code_unit) to a string.
730
731Returns `Err` if the given bytes are invalid UTF-8, and returns `Ok ""` when given `[]`.
732```roc
733expect Str.from_utf8([82, 111, 99]) == Ok("Roc")
734expect Str.from_utf8([233, 185, 143]) == Ok("鹏")
735expect Str.from_utf8([224, 174, 154, 224, 174, 191]) == Ok("சி")
736expect Str.from_utf8([240, 159, 144, 166]) == Ok("🐦")
737expect Str.from_utf8([]) == Ok("")
738expect Str.from_utf8([255]) |> Result.is_err
739```
740
741from_utf8_lossy : List U8 -> Str
742
743Description:
744Converts a [List] of [U8] UTF-8 [code units](https://unicode.org/glossary/#code_unit) to a string.
745Any grouping of invalid byte sequences are replaced with a single unicode replacement character '�'.
746
747An invalid byte sequence is defined as
748- a 2-byte-sequence starting byte, followed by less than 1 continuation byte
749- a 3-byte-sequence starting byte, followed by less than 2 continuation bytes
750- a 4-byte-sequence starting byte, followed by less than 3 continuation bytes
751- an invalid codepoint from the surrogate pair block
752- an invalid codepoint greater than 0x110000 encoded as a 4-byte sequence
753- 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
754
755```roc
756expect (Str.from_utf8_lossy [82, 111, 99, 240, 159, 144, 166]) == "Roc🐦"
757expect (Str.from_utf8_lossy [82, 255, 99]) == "R�c"
758expect (Str.from_utf8_lossy [82, 0xED, 0xA0, 0xBD, 99]) == "R�c"
759```
760
761from_utf16 : List U16 -> Result Str [ BadUtf16 { problem : Utf8Problem, index : U64 } ]
762
763Description:
764Converts a [List] of [U16] UTF-16 (little-endian) [code units](https://unicode.org/glossary/#code_unit) to a string.
765
766```roc
767expect Str.from_utf16([82, 111, 99]) == Ok("Roc")
768expect Str.from_utf16([0xb9a, 0xbbf]) == Ok("சி")
769expect Str.from_utf16([0xd83d, 0xdc26]) == Ok("🐦")
770expect Str.from_utf16([]) == Ok("")
771# unpaired surrogates, first and second halves
772expect Str.from_utf16([82, 0xd83d, 99]) |> Result.is_err
773expect Str.from_utf16([82, 0xdc96, 99]) |> Result.is_err
774```
775
776from_utf16_lossy : List U16 -> Str
777
778Description:
779Converts a [List] of [U16] UTF-16 (little-endian) [code units](https://unicode.org/glossary/#code_unit) to a string.
780Any unpaired surrogate code unit is replaced with a single unicode replacement character '�'.
781
782```roc
783expect Str.from_utf16_lossy([82, 111, 99, 0xd83d, 0xdc26]) == "Roc🐦"
784expect Str.from_utf16_lossy([82, 0xdc96, 99]) == "R�c"
785```
786
787from_utf32 : List U32 -> Result Str [ BadUtf32 { problem : Utf8Problem, index : U64 } ]
788
789from_utf32_lossy : List U32 -> Str
790
791Description:
792Converts a [List] of [U32] UTF-32 [code units](https://unicode.org/glossary/#code_unit) to a string.
793Any invalid code points are replaced with a single unicode replacement character '�'.
794```roc
795expect Str.from_utf32_lossy([82, 111, 99, 0x1f426]) == "Roc🐦"
796expect Str.from_utf32_lossy([82, 0x110000, 99]) == "R�c"
797```
798
799starts_with : Str, Str -> Bool
800
801Description:
802Check if the given [Str] starts with a value.
803```roc
804expect Str.starts_with("ABC", "A") == Bool.true
805expect Str.starts_with("ABC", "X") == Bool.false
806```
807
808ends_with : Str, Str -> Bool
809
810Description:
811Check if the given [Str] ends with a value.
812```roc
813expect Str.ends_with("ABC", "C") == Bool.true
814expect Str.ends_with("ABC", "X") == Bool.false
815```
816
817trim : Str -> Str
818
819Description:
820Return the [Str] with all whitespace removed from both the beginning
821as well as the end.
822```roc
823expect Str.trim(" Hello \n\n") == "Hello"
824```
825
826trim_start : Str -> Str
827
828Description:
829Return the [Str] with all whitespace removed from the beginning.
830```roc
831expect Str.trim_start(" Hello \n\n") == "Hello \n\n"
832```
833
834trim_end : Str -> Str
835
836Description:
837Return the [Str] with all whitespace removed from the end.
838```roc
839expect Str.trim_end(" Hello \n\n") == " Hello"
840```
841
842to_dec : Str -> Result Dec [InvalidNumStr]
843
844Description:
845Encode a [Str] to a [Dec]. A [Dec] value is a 128-bit decimal
846[fixed-point number](https://en.wikipedia.org/wiki/Fixed-point_arithmetic).
847```roc
848expect Str.to_dec("10") == Ok(10dec)
849expect Str.to_dec("-0.25") == Ok(-0.25dec)
850expect Str.to_dec("not a number") == Err(InvalidNumStr)
851```
852
853to_f64 : Str -> Result F64 [InvalidNumStr]
854
855Description:
856Encode a [Str] to a [F64]. A [F64] value is a 64-bit
857[floating-point number](https://en.wikipedia.org/wiki/IEEE_754) and can be
858specified with a `f64` suffix.
859```roc
860expect Str.to_f64("0.10") == Ok(0.10f64)
861expect Str.to_f64("not a number") == Err(InvalidNumStr)
862```
863
864to_f32 : Str -> Result F32 [InvalidNumStr]
865
866Description:
867Encode a [Str] to a [F32].A [F32] value is a 32-bit
868[floating-point number](https://en.wikipedia.org/wiki/IEEE_754) and can be
869specified with a `f32` suffix.
870```roc
871expect Str.to_f32("0.10") == Ok(0.10f32)
872expect Str.to_f32("not a number") == Err(InvalidNumStr)
873```
874
875to_u128 : Str -> Result U128 [InvalidNumStr]
876
877Description:
878Encode a [Str] to an unsigned [U128] integer. A [U128] value can hold numbers
879from `0` to `340_282_366_920_938_463_463_374_607_431_768_211_455` (over
880340 undecillion). It can be specified with a u128 suffix.
881```roc
882expect Str.to_u128("1500") == Ok(1500u128)
883expect Str.to_u128("0.1") == Err(InvalidNumStr)
884expect Str.to_u128("-1") == Err(InvalidNumStr)
885expect Str.to_u128("not a number") == Err(InvalidNumStr)
886```
887
888to_i128 : Str -> Result I128 [InvalidNumStr]
889
890Description:
891Encode a [Str] to a signed [I128] integer. A [I128] value can hold numbers
892from `-170_141_183_460_469_231_731_687_303_715_884_105_728` to
893`170_141_183_460_469_231_731_687_303_715_884_105_727`. It can be specified
894with a i128 suffix.
895```roc
896expect Str.to_u128("1500") == Ok(1500i128)
897expect Str.to_i128("-1") == Ok(-1i128)
898expect Str.to_i128("0.1") == Err(InvalidNumStr)
899expect Str.to_i128("not a number") == Err(InvalidNumStr)
900```
901
902to_u64 : Str -> Result U64 [InvalidNumStr]
903
904Description:
905Encode a [Str] to an unsigned [U64] integer. A [U64] value can hold numbers
906from `0` to `18_446_744_073_709_551_615` (over 18 quintillion). It
907can be specified with a u64 suffix.
908```roc
909expect Str.to_u64("1500") == Ok(1500u64)
910expect Str.to_u64("0.1") == Err(InvalidNumStr)
911expect Str.to_u64("-1") == Err(InvalidNumStr)
912expect Str.to_u64("not a number") == Err(InvalidNumStr)
913```
914
915to_i64 : Str -> Result I64 [InvalidNumStr]
916
917Description:
918Encode a [Str] to a signed [I64] integer. A [I64] value can hold numbers
919from `-9_223_372_036_854_775_808` to `9_223_372_036_854_775_807`. It can be
920specified with a i64 suffix.
921```roc
922expect Str.to_i64("1500") == Ok(1500i64)
923expect Str.to_i64("-1") == Ok(-1i64)
924expect Str.to_i64("0.1") == Err(InvalidNumStr)
925expect Str.to_i64("not a number") == Err(InvalidNumStr)
926```
927
928to_u32 : Str -> Result U32 [InvalidNumStr]
929
930Description:
931Encode a [Str] to an unsigned [U32] integer. A [U32] value can hold numbers
932from `0` to `4_294_967_295` (over 4 billion). It can be specified with
933a u32 suffix.
934```roc
935expect Str.to_u32("1500") == Ok(1500u32)
936expect Str.to_u32("0.1") == Err(InvalidNumStr)
937expect Str.to_u32("-1") == Err(InvalidNumStr)
938expect Str.to_u32("not a number") == Err(InvalidNumStr)
939```
940
941to_i32 : Str -> Result I32 [InvalidNumStr]
942
943Description:
944Encode a [Str] to a signed [I32] integer. A [I32] value can hold numbers
945from `-2_147_483_648` to `2_147_483_647`. It can be
946specified with a i32 suffix.
947```roc
948expect Str.to_i32("1500") == Ok(1500i32)
949expect Str.to_i32("-1") == Ok(-1i32)
950expect Str.to_i32("0.1") == Err(InvalidNumStr)
951expect Str.to_i32("not a number") == Err(InvalidNumStr)
952```
953
954to_u16 : Str -> Result U16 [InvalidNumStr]
955
956Description:
957Encode a [Str] to an unsigned [U16] integer. A [U16] value can hold numbers
958from `0` to `65_535`. It can be specified with a u16 suffix.
959```roc
960expect Str.to_u16("1500") == Ok(1500u16)
961expect Str.to_u16("0.1") == Err(InvalidNumStr)
962expect Str.to_u16("-1") == Err(InvalidNumStr)
963expect Str.to_u16("not a number") == Err(InvalidNumStr)
964```
965
966to_i16 : Str -> Result I16 [InvalidNumStr]
967
968Description:
969Encode a [Str] to a signed [I16] integer. A [I16] value can hold numbers
970from `-32_768` to `32_767`. It can be
971specified with a i16 suffix.
972```roc
973expect Str.to_i16("1500") == Ok(1500i16)
974expect Str.to_i16("-1") == Ok(-1i16)
975expect Str.to_i16("0.1") == Err(InvalidNumStr)
976expect Str.to_i16("not a number") == Err(InvalidNumStr)
977```
978
979to_u8 : Str -> Result U8 [InvalidNumStr]
980
981Description:
982Encode a [Str] to an unsigned [U8] integer. A [U8] value can hold numbers
983from `0` to `255`. It can be specified with a u8 suffix.
984```roc
985expect Str.to_u8("250") == Ok(250u8)
986expect Str.to_u8("-0.1") == Err(InvalidNumStr)
987expect Str.to_u8("not a number") == Err(InvalidNumStr)
988expect Str.to_u8("1500") == Err(InvalidNumStr)
989```
990
991to_i8 : Str -> Result I8 [InvalidNumStr]
992
993Description:
994Encode a [Str] to a signed [I8] integer. A [I8] value can hold numbers
995from `-128` to `127`. It can be
996specified with a i8 suffix.
997```roc
998expect Str.to_i8("-15") == Ok(-15i8)
999expect Str.to_i8("150.00") == Err(InvalidNumStr)
1000expect Str.to_i8("not a number") == Err(InvalidNumStr)
1001```
1002
1003count_utf8_bytes : Str -> U64
1004
1005Description:
1006Gives the number of bytes in a [Str] value.
1007```roc
1008expect Str.count_utf8_bytes("Hello World") == 11
1009```
1010
1011replace_each : Str, Str, Str -> Str
1012
1013Description:
1014Returns the given [Str] with each occurrence of a substring replaced.
1015If the substring is not found, returns the original string.
1016
1017```roc
1018expect Str.replace_each("foo/bar/baz", "/", "_") == "foo_bar_baz"
1019expect Str.replace_each("not here", "/", "_") == "not here"
1020```
1021
1022replace_first : Str, Str, Str -> Str
1023
1024Description:
1025Returns the given [Str] with the first occurrence of a substring replaced.
1026If the substring is not found, returns the original string.
1027
1028```roc
1029expect Str.replace_first("foo/bar/baz", "/", "_") == "foo_bar/baz"
1030expect Str.replace_first("no slashes here", "/", "_") == "no slashes here"
1031```
1032
1033replace_last : Str, Str, Str -> Str
1034
1035Description:
1036Returns the given [Str] with the last occurrence of a substring replaced.
1037If the substring is not found, returns the original string.
1038
1039```roc
1040expect Str.replace_last("foo/bar/baz", "/", "_") == "foo/bar_baz"
1041expect Str.replace_last("no slashes here", "/", "_") == "no slashes here"
1042```
1043
1044split_first : Str, Str -> Result { before : Str, after : Str } [NotFound]
1045
1046Description:
1047Returns the given [Str] before the first occurrence of a [delimiter](https://www.computerhope.com/jargon/d/delimite.htm), as well
1048as the rest of the string after that occurrence.
1049Returns [Err NotFound] if the delimiter is not found.
1050```roc
1051expect Str.split_first("foo/bar/baz", "/") == Ok({ before: "foo", after: "bar/baz" })
1052expect Str.split_first("no slashes here", "/") == Err(NotFound)
1053```
1054
1055split_last : Str, Str -> Result { before : Str, after : Str } [NotFound]
1056
1057Description:
1058Returns the given [Str] before the last occurrence of a delimiter, as well as
1059the rest of the string after that occurrence.
1060Returns [Err NotFound] if the delimiter is not found.
1061```roc
1062expect Str.split_last("foo/bar/baz", "/") == Ok({ before: "foo/bar", after: "baz" })
1063expect Str.split_last("no slashes here", "/") == Err(NotFound)
1064```
1065
1066walk_utf8_with_index : Str, state, (state, U8, U64 -> state) -> state
1067
1068Description:
1069Walks over the `UTF-8` bytes of the given [Str] and calls a function to update
1070state for each byte. The index for that byte in the string is provided
1071to the update function.
1072```roc
1073f : List U8, U8, U64 -> List U8
1074f = \state, byte, _ -> List.append(state, byte)
1075expect Str.walk_utf8_with_index("ABC", [], f) == [65, 66, 67]
1076```
1077
1078walk_utf8 : Str, state, (state, U8 -> state) -> state
1079
1080Description:
1081Walks over the `UTF-8` bytes of the given [Str] and calls a function to update
1082state for each byte.
1083
1084```roc
1085sum_of_utf8_bytes =
1086 Str.walk_utf8("Hello, World!", 0, (\total, byte ->
1087 total + byte
1088 ))
1089
1090expect sum_of_utf8_bytes == 105
1091```
1092
1093release_excess_capacity : Str -> Str
1094
1095Description:
1096Shrink the memory footprint of a str such that its capacity and length are equal.
1097Note: This will also convert seamless slices to regular lists.
1098
1099with_prefix : Str, Str -> Str
1100
1101Description:
1102Adds a prefix to the given [Str].
1103```roc
1104expect Str.with_prefix("Awesome", "Roc") == "RocAwesome"
1105```
1106
1107contains : Str, Str -> Bool
1108
1109Description:
1110Determines whether or not the first Str contains the second.
1111```roc
1112expect Str.contains("foobarbaz", "bar")
1113expect !Str.contains("apple", "orange")
1114expect Str.contains("anything", "")
1115```
1116
1117drop_prefix : Str, Str -> Str
1118
1119Description:
1120Drops the given prefix [Str] from the start of a [Str]
1121If the prefix is not found, returns the original string.
1122
1123```roc
1124expect Str.drop_prefix("bar", "foo") == "bar"
1125expect Str.drop_prefix("foobar", "foo") == "bar"
1126```
1127
1128drop_suffix : Str, Str -> Str
1129
1130Description:
1131Drops the given suffix [Str] from the end of a [Str]
1132If the suffix is not found, returns the original string.
1133
1134```roc
1135expect Str.drop_suffix("bar", "foo") == "bar"
1136expect Str.drop_suffix("barfoo", "foo") == "bar"
1137```
1138
1139with_ascii_lowercased : Str -> Str
1140
1141Description:
1142Returns a version of the string with all [ASCII characters](https://en.wikipedia.org/wiki/ASCII) lowercased.
1143Non-ASCII characters are left unmodified. For example:
1144
1145```roc
1146expect Str.with_ascii_lowercased("CAFÉ") == "cafÉ"
1147```
1148
1149This function is useful for things like [command-line flags](https://en.wikipedia.org/wiki/Command-line_interface#Command-line_option)
1150and [environment variable names](https://en.wikipedia.org/wiki/Environment_variable)
1151where you know in advance that you're dealing with a string containing only ASCII characters.
1152It has better performance than lowercasing operations which take Unicode into account.
1153
1154That said, strings received from user input can always contain
1155non-ASCII Unicode characters, and lowercasing [Unicode](https://unicode.org) works
1156differently in different languages. For example, the string `"I"` lowercases to `"i"`
1157in English and to `"ı"` (a [dotless i](https://en.wikipedia.org/wiki/Dotless_I))
1158in Turkish. These rules can also change in each [Unicode release](https://www.unicode.org/releases/),
1159so we have separate [`unicode` package](https://github.com/roc-lang/unicode)
1160for Unicode capitalization that can be upgraded independently from the language's builtins.
1161
1162To do a case-insensitive comparison of the ASCII characters in a string,
1163you can use [Str.caseless_ascii_equals].
1164
1165with_ascii_uppercased : Str -> Str
1166
1167Description:
1168Returns a version of the string with all [ASCII characters](https://en.wikipedia.org/wiki/ASCII) uppercased.
1169Non-ASCII characters are left unmodified. For example:
1170
1171```roc
1172 expect Str.with_ascii_uppercased("café") == "CAFé"
1173```
1174
1175This function is useful for things like
1176[command-line flags](https://en.wikipedia.org/wiki/Command-line_interface#Command-line_option)
1177and [environment variable names](https://en.wikipedia.org/wiki/Environment_variable)
1178where you know in advance that you're dealing with a string containing only ASCII characters.
1179It has better performance than lowercasing operations which take Unicode into account.
1180
1181That said, strings received from user input can always contain
1182non-ASCII Unicode characters, and uppercasing [Unicode](https://unicode.org)
1183works differently in different languages.
1184For example, the string `"i"` uppercases to `"I"` in English and to `"İ"`
1185(a [dotted I](https://en.wikipedia.org/wiki/%C4%B0)) in Turkish.
1186These rules can also change in each Unicode release,
1187so we have a separate [`unicode` package](https://github.com/roc-lang/unicode) for Unicode capitalization
1188that can be upgraded independently from the language's builtins.
1189
1190To do a case-insensitive comparison of the ASCII characters in a string,
1191you can use [Str.caseless_ascii_equals].
1192
1193caseless_ascii_equals : Str, Str -> Bool
1194
1195Description:
1196Returns `True` if all the [ASCII characters](https://en.wikipedia.org/wiki/ASCII) in the string are the same
1197when ignoring differences in capitalization.
1198Non-ASCII characters must all be exactly the same,
1199including capitalization. For example:
1200
1201```roc
1202 expect Str.caseless_ascii_equals("café", "CAFé")
1203
1204 expect !Str.caseless_ascii_equals("café", "CAFÉ")
1205```
1206
1207The first call returns `True` because all the ASCII characters are the same
1208when ignoring differences in capitalization, and the only non-ASCII character
1209(`é`) is the same in both strings. The second call returns `False`because
1210`é` and `É` are not ASCII characters, and they are different.
1211
1212This function is useful for things like [command-line flags](https://en.wikipedia.org/wiki/Command-line_interface#Command-line_option)
1213and [environment variable names](https://en.wikipedia.org/wiki/Environment_variable)
1214where you know in advance that you're dealing with a string containing only ASCII characters.
1215It has better performance than lowercasing operations which take Unicode into account.
1216
1217That said, strings received from user input can always contain
1218non-ASCII Unicode characters, and lowercasing [Unicode](https://unicode.org) works
1219differently in different languages. For example, the string `"I"` lowercases to `"i"`
1220in English and to `"ı"` (a [dotless i](https://en.wikipedia.org/wiki/Dotless_I))
1221in Turkish. These rules can also change in each [Unicode release](https://www.unicode.org/releases/),
1222so we have separate [`unicode` package](https://github.com/roc-lang/unicode)
1223for Unicode capitalization that can be upgraded independently from the language's builtins.
1224
1225To convert a string's ASCII characters to uppercase or lowercase, you can use [Str.with_ascii_uppercased]
1226or [Str.with_ascii_lowercased].
1227
1228### Num
1229
1230Description:
1231Represents a number that could be either an [Int] or a [Frac].
1232
1233This is useful for functions that can work on either, for example [Num.add], whose type is:
1234```roc
1235add : Num a, Num a -> Num a
1236```
1237The number 1.5 technically has the type `Num (Fraction *)`, so when you pass
1238two of them to [Num.add], the answer you get is `3.0 : Num (Fraction *)`.
1239
1240Similarly, the number 0x1 (that is, the integer 1 in hexadecimal notation)
1241technically has the type `Num (Integer *)`, so when you pass two of them to
1242[Num.add], the answer you get is `2 : Num (Integer *)`.
1243
1244The type [`Frac a`](#Frac) is defined to be an alias for `Num (Fraction a)`,
1245so `3.0 : Num (Fraction *)` is the same value as `3.0 : Frac *`.
1246Similarly, the type [`Int a`](#Int) is defined to be an alias for
1247`Num (Integer a)`, so `2 : Num (Integer *)` is the same value as
1248`2 : Int *`.
1249
1250In this way, the [Num] type makes it possible to have `1 + 0x1` return
1251`2 : Int *` and `1.5 + 1.5` return `3.0 : Frac`.
1252
1253## Number Literals
1254
1255Number literals without decimal points (like `0`, `4` or `360`)
1256have the type `Num *` at first, but usually end up taking on
1257a more specific type based on how they're used.
1258
1259For example, in `1 + List.len(my_list)`, the `1` has the type `Num *` at first,
1260but because `List.len` returns a `U64`, the `1` ends up changing from
1261`Num *` to the more specific `U64`, and the expression as a whole
1262ends up having the type `U64`.
1263
1264Sometimes number literals don't become more specific. For example,
1265the `Num.to_str` function has the type `Num * -> Str`. This means that
1266when calling `Num.to_str(5 + 6)`, the expression `5 + 6`
1267still has the type `Num *`. When this happens, `Num *` defaults to
1268being an [I64] - so this addition expression would overflow
1269if either 5 or 6 were replaced with a number big enough to cause
1270addition overflow on an [I64] value.
1271
1272If this default of [I64] is not big enough for your purposes,
1273you can add an `i128` to the end of the number literal, like so:
1274```roc
1275Num.to_str(5_000_000_000i128)
1276```
1277This `i128` suffix specifies that you want this number literal to be
1278an [I128] instead of a `Num *`. All the other numeric types have
1279suffixes just like `i128`; here are some other examples:
1280
1281* `215u8` is a `215` value of type [U8]
1282* `76.4f32` is a `76.4` value of type [F32]
1283* `123.45dec` is a `123.45` value of type [Dec]
1284
1285In practice, these are rarely needed. It's most common to write
1286number literals without any suffix.
1287
1288Description:
1289A fixed-size integer - that is, a number with no fractional component.
1290
1291Integers come in two flavors: signed and unsigned. Signed integers can be
1292negative ("signed" refers to how they can incorporate a minus sign),
1293whereas unsigned integers cannot be negative.
1294
1295Since integers have a fixed size, the size you choose determines both the
1296range of numbers it can represent, and also how much memory it takes up.
1297
1298[U8] is an an example of an integer. It is an unsigned [Int] that takes up 8 bits
1299(aka 1 byte) in memory. The `U` is for Unsigned and the 8 is for 8 bits.
1300Because it has 8 bits to work with, it can store 256 numbers (2^8),
1301and because it is unsigned, its min value is 0. This means the 256 numbers
1302it can store range from 0 to 255.
1303
1304[I8] is a signed integer that takes up 8 bits. The `I` is for Integer, since
1305integers in mathematics are signed by default. Because it has 8 bits just
1306like [U8], it can store 256 numbers (still 2^8), but because it is signed,
1307the range is different. Its 256 numbers range from -128 to 127.
1308
1309Here are some other examples:
1310
1311* [U16] is like [U8], except it takes up 16 bits in memory. It can store 65,536 numbers (2^16), ranging from 0 to 65,536.
1312* [I16] is like [U16], except it is signed. It can still store the same 65,536 numbers (2^16), ranging from -32,768 to 32,767.
1313
1314This pattern continues up to [U128] and [I128].
1315
1316## Performance Details
1317
1318In general, using smaller numeric sizes means your program will use less memory.
1319However, if a mathematical operation results in an answer that is too big
1320or too small to fit in the size available for that answer (which is typically
1321the same size as the inputs), then you'll get an overflow error.
1322
1323As such, minimizing memory usage without causing overflows involves choosing
1324number sizes based on your knowledge of what numbers you expect your program
1325to encounter at runtime.
1326
1327Minimizing memory usage does not imply maximum runtime speed!
1328CPUs are typically fastest at performing integer operations on integers that
1329are the same size as that CPU's native machine word size. That means a 64-bit
1330CPU is typically fastest at executing instructions on [U64] and [I64] values,
1331whereas a 32-bit CPU is typically fastest on [U32] and [I32] values.
1332
1333Putting these factors together, here are some reasonable guidelines for optimizing performance through integer size choice:
1334
1335* Start by deciding if this integer should allow negative numbers, and choose signed or unsigned accordingly.
1336* Next, think about the range of numbers you expect this number to hold. Choose the smallest size you will never expect to overflow, no matter the inputs your program receives. (Validating inputs for size, and presenting the user with an error if they are too big, can help guard against overflow.)
1337* Finally, if a particular numeric calculation is running too slowly, you can try experimenting with other number sizes. This rarely makes a meaningful difference, but some processors can operate on different number sizes at different speeds.
1338
1339All number literals without decimal points are compatible with [Int] values.
1340
1341You can optionally put underscores in your [Int] literals.
1342They have no effect on the number's value, but can make large numbers easier to read.
1343```roc
13441_000_000
1345```
1346Integers come in two flavors: *signed* and *unsigned*.
1347
1348* *Unsigned* integers can never be negative. The lowest value they can hold is zero.
1349* *Signed* integers can be negative.
1350
1351Integers also come in different sizes. Choosing a size depends on your performance
1352needs and the range of numbers you need to represent. At a high level, the
1353general trade-offs are:
1354
1355* Larger integer sizes can represent a wider range of numbers. If you absolutely need to represent numbers in a certain range, make sure to pick an integer size that can hold them!
1356* Smaller integer sizes take up less memory. These savings rarely matter in variables and function arguments, but the sizes of integers that you use in data structures can add up. This can also affect whether those data structures fit in [cache lines](https://en.wikipedia.org/wiki/CPU_cache#Cache_performance), which can be a performance bottleneck.
1357* Certain CPUs work faster on some numeric sizes than others. If the CPU is taking too long to run numeric calculations, you may find a performance improvement by experimenting with numeric sizes that are larger than otherwise necessary. However, in practice, doing this typically degrades overall performance, so be careful to measure properly!
1358
1359Here are the different fixed size integer types:
1360
1361| Range | Type | Size |
1362|--------------------------------------------------------|-------|----------|
1363| ` -128` | [I8] | 1 Byte |
1364| ` 127` | | |
1365|--------------------------------------------------------|-------|----------|
1366| ` 0` | [U8] | 1 Byte |
1367| ` 255` | | |
1368|--------------------------------------------------------|-------|----------|
1369| ` -32_768` | [I16] | 2 Bytes |
1370| ` 32_767` | | |
1371|--------------------------------------------------------|-------|----------|
1372| ` 0` | [U16] | 2 Bytes |
1373| ` 65_535` | | |
1374|--------------------------------------------------------|-------|----------|
1375| ` -2_147_483_648` | [I32] | 4 Bytes |
1376| ` 2_147_483_647` | | |
1377|--------------------------------------------------------|-------|----------|
1378| ` 0` | [U32] | 4 Bytes |
1379| ` (over 4 billion) 4_294_967_295` | | |
1380|--------------------------------------------------------|-------|----------|
1381| ` -9_223_372_036_854_775_808` | [I64] | 8 Bytes |
1382| ` 9_223_372_036_854_775_807` | | |
1383|--------------------------------------------------------|-------|----------|
1384| ` 0` | [U64] | 8 Bytes |
1385| ` (over 18 quintillion) 18_446_744_073_709_551_615` | | |
1386|--------------------------------------------------------|-------|----------|
1387| `-170_141_183_460_469_231_731_687_303_715_884_105_728` | [I128]| 16 Bytes |
1388| ` 170_141_183_460_469_231_731_687_303_715_884_105_727` | | |
1389|--------------------------------------------------------|-------|----------|
1390| ` (over 340 undecillion) 0` | [U128]| 16 Bytes |
1391| ` 340_282_366_920_938_463_463_374_607_431_768_211_455` | | |
1392
1393If any operation would result in an [Int] that is either too big
1394or too small to fit in that range (e.g. calling `Num.max_i32 + 1`),
1395then the operation will *overflow*. When an overflow occurs, the program will crash.
1396
1397As such, it's very important to design your code not to exceed these bounds!
1398If you need to do math outside these bounds, consider using a larger numeric size.
1399
1400Description:
1401A fixed-size number with a fractional component.
1402
1403Roc fractions come in two flavors: fixed-point base-10 and floating-point base-2.
1404
1405* [Dec] is a 128-bit [fixed-point](https://en.wikipedia.org/wiki/Fixed-point_arithmetic) base-10 number. It's a great default choice, especially when precision is important - for example when representing currency. With [Dec], `0.1 + 0.2` returns `0.3`. [Dec] has 18 decimal places of precision and a range from `-170_141_183_460_469_231_731.687303715884105728` to `170_141_183_460_469_231_731.687303715884105727`.
1406* [F64] and [F32] are [floating-point](https://en.wikipedia.org/wiki/Floating-point_arithmetic) base-2 numbers. They sacrifice precision for lower memory usage and improved performance on some operations. This makes them a good fit for representing graphical coordinates. With [F64], `0.1 + 0.2` returns `0.30000000000000004`.
1407
1408If you don't specify a type, Roc will default to using [Dec] because it's
1409the least error-prone overall. For example, suppose you write this:
1410```roc
1411was_it_precise = 0.1 + 0.2 == 0.3
1412```
1413The value of `was_it_precise` here will be `Bool.true`, because Roc uses [Dec]
1414by default when there are no types specified.
1415
1416In contrast, suppose we use `f32` or `f64` for one of these numbers:
1417```roc
1418was_it_precise = 0.1f64 + 0.2 == 0.3
1419```
1420Here, `was_it_precise` will be `Bool.false` because the entire calculation will have
1421been done in a base-2 floating point calculation, which causes noticeable
1422precision loss in this case.
1423
1424The floating-point numbers ([F32] and [F64]) also have three values which
1425are not ordinary [finite numbers](https://en.wikipedia.org/wiki/Finite_number).
1426They are:
1427* ∞ ([infinity](https://en.wikipedia.org/wiki/Infinity))
1428* -∞ (negative infinity)
1429* *NaN* ([not a number](https://en.wikipedia.org/wiki/NaN))
1430
1431These values are different from ordinary numbers in that they only occur
1432when a floating-point calculation encounters an error. For example:
1433* Dividing a positive [F64] by `0.0` returns ∞.
1434* Dividing a negative [F64] by `0.0` returns -∞.
1435* Dividing a [F64] of `0.0` by `0.0` returns [*NaN*](Num#is_nan).
1436
1437These rules come from the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
1438floating point standard. Because almost all modern processors are built to
1439this standard, deviating from these rules has a significant performance
1440cost! Since the most common reason to choose [F64] or [F32] over [Dec] is
1441access to hardware-accelerated performance, Roc follows these rules exactly.
1442
1443There's no literal syntax for these error values, but you can check to see if
1444you ended up with one of them by using #is_nan, #is_finite, and #is_infinite.
1445Whenever a function in this module could return one of these values, that
1446possibility is noted in the function's documentation.
1447
1448## Performance Details
1449
1450On typical modern CPUs, performance is similar between [Dec], [F64], and [F32]
1451for addition and subtraction. For example, [F32] and [F64] do addition using
1452a single CPU floating-point addition instruction, which typically takes a
1453few clock cycles to complete. In contrast, [Dec] does addition using a few
1454CPU integer arithmetic instructions, each of which typically takes only one
1455clock cycle to complete. Exact numbers will vary by CPU, but they should be
1456similar overall.
1457
1458[Dec] is significantly slower for multiplication and division. It not only
1459needs to do more arithmetic instructions than [F32] and [F64] do, but also
1460those instructions typically take more clock cycles to complete.
1461
1462With [Num.sqrt] and trigonometry functions like [Num.cos], there is
1463an even bigger performance difference. [F32] and [F64] can do these in a
1464single instruction, whereas [Dec] needs entire custom procedures - which use
1465loops and conditionals. If you need to do performance-critical trigonometry
1466or square roots, either [F64] or [F32] is probably a better choice than the
1467usual default choice of [Dec], despite the precision problems they bring.
1468
1469Description:
1470A signed 8-bit integer, ranging from -128 to 127
1471
1472Description:
1473A 64-bit [IEEE 754 binary floating-point number](https://en.wikipedia.org/wiki/IEEE_754).
1474
1475[F64] represents decimal numbers less precisely than [Dec] does, but operations on it
1476can be faster because CPUs have hardware-level support for [F64] but not [Dec]. There
1477are other tradeoffs between the two, such as:
1478* [Dec] has a fixed number of digits it can represent before the decimal point, and a fixed number it can represent after the decimal point. In contrast, [F64]'s decimal point can "float"—which conceptually means if you don't need many digits before the decimal point, you can get more digits of precision afterwards (and vice versa).
1479* [Dec] represents its number internally in [base-10](https://en.wikipedia.org/wiki/Decimal), whereas [F64] uses [base-2](https://en.wikipedia.org/wiki/Binary_number). This can lead to imprecise answers like `0.1 + 0.2` returning `0.3` for [Dec] and `0.30000000000000004` for [F64]. This is not a bug; rather, it's a consequence of [F64]'s base-2 representation.
1480* [Dec] always gives a precise answer (or an error), whereas [F64] can lose precision. For example, increasing a very large [F64] number (using addition, perhaps) can result in the whole number portion being incorrect. `1234567890123456789 + 100` correctly results in a number ending in `889` for `Dec`, but results in a number ending `800` in [F64] due to precision loss.
1481
1482Description:
1483A 32-bit [IEEE 754 binary floating-point number](https://en.wikipedia.org/wiki/IEEE_754).
1484
1485This works just like [F64] (see its docs for a comparison with [Dec]) except it's smaller.
1486That in turn means it takes up less memory, but can store smaller numbers (and becomes imprecise
1487more easily than [F64] does).
1488
1489Description:
1490A [decimal](https://en.wikipedia.org/wiki/Decimal) number.
1491
1492[Dec] is a more precise way to represent decimal numbers (like currency) than [F32] and [F64]
1493are, because [Dec] is represented in memory as base-10. In contrast, [F64] and [F32]
1494are [base-2](https://en.wikipedia.org/wiki/Binary_number) in memory, which can lead to decimal
1495precision loss even when doing addition and subtraction. For example, when
1496using [F64], `0.1 + 0.2` returns 0.30000000000000004,
1497whereas when using [Dec], `0.1 + 0.2` returns 0.3.
1498
1499Under the hood, a [Dec] is an [I128], and operations on it perform
1500[base-10 fixed-point arithmetic](https://en.wikipedia.org/wiki/Fixed-point_arithmetic)
1501with 18 decimal places of precision.
1502
1503This means a [Dec] can represent whole numbers up to slightly over 170
1504quintillion, along with 18 decimal places. (To be precise, it can store
1505numbers between `-170_141_183_460_469_231_731.687303715884105728`
1506and `170_141_183_460_469_231_731.687303715884105727`.) Why 18
1507decimal places? It's the highest number of decimal places where you can
1508still convert any [U64] to a [Dec] without losing information.
1509
1510There are some use cases where [F64] and [F32] can be better choices than [Dec]
1511despite their issues with base-10 numbers. For example, in graphical applications
1512they can be a better choice for representing coordinates because they take up
1513less memory, certain relevant calculations run faster (see performance
1514details, below), and base-10 generally isn't as big a concern when
1515dealing with screen coordinates as it is when dealing with currency.
1516
1517Another scenario where [F64] can be a better choice than [Dec] is when representing
1518extremely small numbers. The smallest positive [F64] that can be represented without precision
1519loss is 2^(−1074), which is about 5 * 10^(-324). Here is that number next to the smallest
1520[Dec] that can be represented:
1521
1522* Smallest [F64]: 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005
1523* Smallest [Dec]: 0.000000000000000001
1524
1525This is because [floating-point](https://en.wikipedia.org/wiki/Floating-point_arithmetic) numbers
1526like [F64] can gain more digits of precision after the `.` when they aren't using as many digits
1527before the `.` - and this applies the most if the digit before `.` is `0`. So whereas [Dec] always
1528has 18 digits after the `.`, the number of digits after the `.` that [F32] can [F64] can represent
1529without precision loss depends on what comes before it.
1530
1531## Performance Details
1532
1533CPUs have dedicated instructions for many [F32] and [F64] operations, but none for [Dec].
1534Internally, [Dec] is represented as a 128-bit integer and uses multiple instructions to
1535perform fractional operations. This gives [F32] and [F64] performance advantages
1536for many operations.
1537
1538Here's a comparison of about how long [Dec] takes to perform a given operation compared to [F64],
1539based on benchmarks on an [M1](https://en.wikipedia.org/wiki/Apple_M1) CPU:
1540* [add] 0.6x
1541* [sub] 0.6x
1542* [mul] 15x
1543* [div] 55x
1544* [sin] 3.9x
1545* [cos] 3.6x
1546* [tan] 2.3x
1547* [asin] 1.8x
1548* [acos] 1.7x
1549* [atan] 1.7x
1550
1551Keep in mind that arithmetic instructions are basically [the fastest thing a CPU does](http://norvig.com/21-days.html#answers),
1552so (for example) a network request that takes 10 milliseconds to complete would go on this
1553list as about 10000000x. So these performance differences might be more or less noticeable than
1554the base-10 representation differences depending on the use case.
1555
1556e : Frac *
1557
1558Description:
1559Euler's number (e)
1560
1561pi : Frac *
1562
1563Description:
1564Archimedes' constant (π)
1565
1566tau : Frac *
1567
1568Description:
1569Circle constant (τ)
1570
1571to_str : Num * -> Str
1572
1573Description:
1574Convert a number to a [Str].
1575
1576```roc
1577Num.to_str(42)
1578```
1579Only [Frac] values will include a decimal point, and they will always include one.
1580```roc
1581Num.to_str(4.2)
1582Num.to_str(4.0)
1583```
1584When this function is given a non-[finite](Num#is_finite)
1585[F64] or [F32] value, the returned string will be `"NaN"`, `"∞"`, or `"-∞"`.
1586
1587
1588int_cast : Int a -> Int b
1589
1590Description:
1591Convert an [Int] to a new [Int] of the expected type:
1592
1593```roc
1594# Casts a U8 to a U16
1595x : U16
1596x = Num.int_cast(255u8)
1597```
1598
1599In the case of downsizing, information is lost:
1600
1601```roc
1602# returns 0, as the bits were truncated.
1603x : U8
1604x = Num.int_cast(256u16)
1605```
1606
1607
1608compare : Num a, Num a -> [ LT, EQ, GT ]
1609
1610is_lt : Num a, Num a -> Bool
1611
1612Description:
1613Returns `Bool.true` if the first number is less than the second.
1614
1615`a < b` is shorthand for `Num.is_lt(a, b)`.
1616
1617If either argument is [*NaN*](Num#is_nan), returns `Bool.false` no matter what. (*NaN*
1618is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
1619```roc
16205
1621 |> Num.is_lt 6
1622```
1623
1624is_gt : Num a, Num a -> Bool
1625
1626Description:
1627Returns `Bool.true` if the first number is greater than the second.
1628
1629`a > b` is shorthand for `Num.is_gt a b`.
1630
1631If either argument is [*NaN*](Num#is_nan), returns `Bool.false` no matter what. (*NaN*
1632is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
1633```roc
1634Num.is_gt(6, 5)
1635```
1636
1637is_lte : Num a, Num a -> Bool
1638
1639Description:
1640Returns `Bool.true` if the first number is less than or equal to the second.
1641
1642`a <= b` is shorthand for `Num.is_lte(a, b)`.
1643
1644If either argument is [*NaN*](Num#is_nan), returns `Bool.false` no matter what. (*NaN*
1645is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
1646
1647is_gte : Num a, Num a -> Bool
1648
1649Description:
1650Returns `Bool.true` if the first number is greater than or equal to the second.
1651
1652`a >= b` is shorthand for `Num.is_gte(a, b)`.
1653
1654If either argument is [*NaN*](Num#is_nan), returns `Bool.false` no matter what. (*NaN*
1655is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
1656
1657is_approx_eq : Frac a, Frac a, { rtol ? Frac a, atol ? Frac a } -> Bool
1658
1659Description:
1660Returns `Bool.true` if the first number and second number are within a specific threshold
1661
1662A specific relative and absolute tolerance can be provided to change the threshold
1663
1664This function is symmetric: `Num.is_approx_eq(a, b) == Num.is_approx_eq(b, a)`
1665
1666If either argument is [*NaN*](Num#is_nan), returns `Bool.false` no matter what. (*NaN*
1667is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
1668
1669is_zero : Num a -> Bool
1670
1671Description:
1672Returns `Bool.true` if the number is `0`, and `Bool.false` otherwise.
1673
1674is_even : Int a -> Bool
1675
1676Description:
1677A number is even if dividing it by 2 gives a remainder of 0.
1678
1679Examples of even numbers: 0, 2, 4, 6, 8, -2, -4, -6, -8
1680
1681is_odd : Int a -> Bool
1682
1683Description:
1684A number is odd if dividing it by 2 gives a remainder of 1.
1685
1686Examples of odd numbers: 1, 3, 5, 7, -1, -3, -5, -7
1687
1688is_positive : Num a -> Bool
1689
1690Description:
1691Positive numbers are greater than `0`.
1692
1693is_negative : Num a -> Bool
1694
1695Description:
1696Negative numbers are less than `0`.
1697
1698to_frac : Num * -> Frac *
1699
1700is_nan : Frac * -> Bool
1701
1702Description:
1703Returns `Bool.true` if the [Frac] is not a number as defined by [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
1704
1705```roc
1706Num.is_nan(0 / 0)
1707```
1708
1709is_infinite : Frac * -> Bool
1710
1711Description:
1712Returns `Bool.true` if the [Frac] is positive or negative infinity as defined by [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
1713
1714```roc
1715Num.is_infinite(1 / 0)
1716
1717Num.is_infinite(-1 / 0)
1718```
1719
1720is_finite : Frac * -> Bool
1721
1722Description:
1723Returns `Bool.true` if the [Frac] is not an infinity as defined by [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
1724
1725```roc
1726Num.is_finite(42)
1727```
1728
1729abs : Num a -> Num a
1730
1731Description:
1732Returns the absolute value of the number.
1733
1734* For a positive number, returns the same number.
1735* For a negative number, returns the same number except positive.
1736* For zero, returns zero.
1737```roc
1738Num.abs(4)
1739
1740Num.abs(-2.5)
1741
1742Num.abs(0)
1743
1744Num.abs(0.0)
1745```
1746This is safe to use with any [Frac], but it can cause overflow when used with certain [Int] values.
1747
1748For example, calling #Num.abs on the lowest value of a signed integer (such as [Num.min_i64] or [Num.min_i32]) will cause overflow.
1749This 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
1750the highest value it can represent. (For this reason, calling [Num.neg] on the lowest signed value will also cause overflow.)
1751
1752Calling this on an unsigned integer (like [U32] or [U64]) never does anything.
1753
1754abs_diff : Num a, Num a -> Num a
1755
1756Description:
1757Returns the absolute difference between two numbers.
1758
1759```roc
1760Num.abs_diff(5, 3)
1761
1762Num.abs_diff(-3, 5)
1763
1764Num.abs_diff(3.0, 5.0)
1765```
1766
1767If the answer to this operation can't fit in the return value (e.g. an
1768[I8] answer that's higher than 127 or lower than -128), the result is an
1769*overflow*. For [F64] and [F32], overflow results in an answer of either
1770∞ or -∞. For all other number types, overflow results in a panic.
1771
1772neg : Num a -> Num a
1773
1774Description:
1775Returns a negative number when given a positive one, and vice versa.
1776```roc
1777Num.neg(5)
1778
1779Num.neg(-2.5)
1780
1781Num.neg(0)
1782
1783Num.neg(0.0)
1784```
1785!! Num.neg is not completely implemented for all types in all contexts, see github.com/roc-lang/roc/issues/6959
1786You can use `\some_num -> 0 - some_num` as a workaround.
1787
1788This is safe to use with any [Frac], but it can cause overflow when used with certain [Int] values.
1789
1790For example, calling #Num.neg on the lowest value of a signed integer (such as [Num.min_i64] or [Num.min_i32]) will cause overflow.
1791This 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
1792the highest value it can represent. (For this reason, calling #Num.abs on the lowest signed value will also cause overflow.)
1793
1794Additionally, calling #Num.neg on any unsigned integer (such as any [U64] or [U32] value) other than zero will cause overflow.
1795
1796(It will never crash when given a [Frac], however, because of how floating point numbers represent positive and negative numbers.)
1797
1798add : Num a, Num a -> Num a
1799
1800Description:
1801Adds two numbers of the same type.
1802
1803(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.)
1804
1805`a + b` is shorthand for `Num.add(a, b)`.
1806```roc
18075 + 7
1808
1809Num.add(5, 7)
1810```
1811`Num.add` can be convenient in pipelines.
1812```roc
1813Frac.pi
1814 |> Num.add(1.0)
1815```
1816If the answer to this operation can't fit in the return value (e.g. an
1817[I8] answer that's higher than 127 or lower than -128), the result is an
1818*overflow*. For [F64] and [F32], overflow results in an answer of either
1819∞ or -∞. For all other number types, overflow results in a panic.
1820
1821sub : Num a, Num a -> Num a
1822
1823Description:
1824Subtracts two numbers of the same type.
1825
1826(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.)
1827
1828`a - b` is shorthand for `Num.sub(a, b)`.
1829```roc
18307 - 5
1831
1832Num.sub(7, 5)
1833```
1834`Num.sub` can be convenient in pipelines.
1835```roc
1836Frac.pi
1837 |> Num.sub(2.0)
1838```
1839If the answer to this operation can't fit in the return value (e.g. an
1840[I8] answer that's higher than 127 or lower than -128), the result is an
1841*overflow*. For [F64] and [F32], overflow results in an answer of either
1842∞ or -∞. For all other number types, overflow results in a panic.
1843
1844mul : Num a, Num a -> Num a
1845
1846Description:
1847Multiplies two numbers of the same type.
1848
1849(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.)
1850
1851`a * b` is shorthand for `Num.mul(a, b)`.
1852```roc
18535 * 7
1854
1855Num.mul(5, 7)
1856```
1857
1858`Num.mul` can be convenient in pipelines.
1859
1860```roc
1861Frac.pi
1862 |> Num.mul(2.0)
1863```
1864If the answer to this operation can't fit in the return value (e.g. an
1865[I8] answer that's higher than 127 or lower than -128), the result is an
1866*overflow*. For [F64] and [F32], overflow results in an answer of either
1867∞ or -∞. For all other number types, overflow results in a panic.
1868
1869min : Num a, Num a -> Num a
1870
1871Description:
1872Obtains the smaller between two numbers of the same type.
1873
1874```roc
1875Num.min(100, 0)
1876
1877Num.min(3.0, -3.0)
1878```
1879
1880max : Num a, Num a -> Num a
1881
1882Description:
1883Obtains the greater between two numbers of the same type.
1884
1885```roc
1886Num.max(100, 0)
1887
1888Num.max(3.0, -3.0)
1889```
1890
1891sin : Frac a -> Frac a
1892
1893cos : Frac a -> Frac a
1894
1895tan : Frac a -> Frac a
1896
1897asin : Frac a -> Frac a
1898
1899acos : Frac a -> Frac a
1900
1901atan : Frac a -> Frac a
1902
1903sqrt : Frac a -> Frac a
1904
1905Description:
1906Returns an approximation of the absolute value of a [Frac]'s square root.
1907
1908The square root of a negative number is an irrational number, and [Frac] only
1909supports rational numbers. As such, you should make sure never to pass this
1910function a negative number! Calling [sqrt] on a negative [Dec] will cause a panic.
1911
1912Calling [sqrt] on [F32] and [F64] values follows these rules:
1913* Passing a negative [F64] or [F32] returns [*NaN*](Num#is_nan).
1914* Passing [*NaN*](Num#is_nan) or -∞ also returns [*NaN*](Num#is_nan).
1915* Passing ∞ returns ∞.
1916
1917> These rules come from the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
1918> floating point standard. Because almost all modern processors are built to
1919> this standard, deviating from these rules has a significant performance
1920> cost! Since the most common reason to choose [F64] or [F32] over [Dec] is
1921> access to hardware-accelerated performance, Roc follows these rules exactly.
1922```roc
1923Num.sqrt(4.0)
1924
1925Num.sqrt(1.5)
1926
1927Num.sqrt(0.0)
1928
1929Num.sqrt(-4.0f64)
1930```
1931
1932sqrt_checked : Frac a -> Result (Frac a) [SqrtOfNegative]
1933
1934log : Frac a -> Frac a
1935
1936Description:
1937Natural logarithm
1938
1939log_checked : Frac a -> Result (Frac a) [LogNeedsPositive]
1940
1941div : Frac a, Frac a -> Frac a
1942
1943Description:
1944Divides one [Frac] by another.
1945
1946`a / b` is shorthand for `Num.div(a, b)`.
1947
1948[Division by zero is undefined in mathematics](https://en.wikipedia.org/wiki/Division_by_zero).
1949As such, you should make sure never to pass zero as the denominator to this function!
1950Calling [div] on a [Dec] denominator of zero will cause a panic.
1951
1952Calling [div] on [F32] and [F64] values follows these rules:
1953* Dividing a positive [F64] or [F32] by zero returns ∞.
1954* Dividing a negative [F64] or [F32] by zero returns -∞.
1955* Dividing a zero [F64] or [F32] by zero returns [*NaN*](Num#is_nan).
1956
1957> These rules come from the [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754)
1958> floating point standard. Because almost all modern processors are built to
1959> this standard, deviating from these rules has a significant performance
1960> cost! Since the most common reason to choose [F64] or [F32] over [Dec] is
1961> access to hardware-accelerated performance, Roc follows these rules exactly.
1962
1963To divide an [Int] and a [Frac], first convert the [Int] to a [Frac] using
1964one of the functions in this module like #to_dec.
1965```roc
19665.0 / 7.0
1967
1968Num.div(5, 7)
1969```
1970`Num.div` can be convenient in pipelines.
1971```roc
1972Num.pi
1973 |> Num.div (2.0)
1974```
1975
1976div_checked : Frac a, Frac a -> Result (Frac a) [DivByZero]
1977
1978div_ceil : Int a, Int a -> Int a
1979
1980div_ceil_checked : Int a, Int a -> Result (Int a) [DivByZero]
1981
1982div_trunc : Int a, Int a -> Int a
1983
1984Description:
1985Divides two integers, truncating the result towards zero.
1986
1987`a // b` is shorthand for `Num.div_trunc(a, b)`.
1988
1989Division by zero is undefined in mathematics. As such, you should make
1990sure never to pass zero as the denominator to this function! If you do,
1991it will crash.
1992```roc
19935 // 7
1994
1995Num.div_trunc(5, 7)
1996
19978 // -3
1998
1999Num.div_trunc(8, -3)
2000```
2001
2002div_trunc_checked : Int a, Int a -> Result (Int a) [DivByZero]
2003
2004rem : Int a, Int a -> Int a
2005
2006Description:
2007Obtains the remainder (truncating modulo) from the division of two integers.
2008
2009`a % b` is shorthand for `Num.rem(a, b)`.
2010```roc
20115 % 7
2012
2013Num.rem(5, 7)
2014
2015-8 % -3
2016
2017Num.rem(-8, -3)
2018```
2019
2020rem_checked : Int a, Int a -> Result (Int a) [DivByZero]
2021
2022is_multiple_of : Int a, Int a -> Bool
2023
2024bitwise_and : Int a, Int a -> Int a
2025
2026Description:
2027Does a "bitwise and". Each bit of the output is 1 if the corresponding bit
2028of x AND of y is 1, otherwise it's 0.
2029
2030bitwise_xor : Int a, Int a -> Int a
2031
2032Description:
2033Does a "bitwise exclusive or". Each bit of the output is the same as the
2034corresponding bit in x if that bit in y is 0, and it's the complement of
2035the bit in x if that bit in y is 1.
2036
2037bitwise_or : Int a, Int a -> Int a
2038
2039Description:
2040Does a "bitwise or". Each bit of the output is 0 if the corresponding bit
2041of x OR of y is 0, otherwise it's 1.
2042
2043bitwise_not : Int a -> Int a
2044
2045Description:
2046Returns the complement of x - the number you get by switching each 1 for a
20470 and each 0 for a 1. This is the same as -x - 1.
2048
2049shift_left_by : Int a, U8 -> Int a
2050
2051Description:
2052Bitwise left shift of a number by another
2053
2054The least significant bits always become 0. This means that shifting left is
2055like multiplying by factors of two for unsigned integers.
2056```roc
2057shift_left_by(0b0000_0011, 2) == 0b0000_1100
2058
20590b0000_0101 |> shift_left_by(2) == 0b0001_0100
2060```
2061In some languages `shift_left_by` is implemented as a binary operator `<<`.
2062
2063shift_right_by : Int a, U8 -> Int a
2064
2065Description:
2066Bitwise arithmetic shift of a number by another
2067
2068The most significant bits are copied from the current.
2069```roc
2070shift_right_by(0b0000_1100, 2) == 0b0000_0011
2071
20720b0001_0100 |> shift_right_by(2) == 0b0000_0101
2073
20740b1001_0000 |> shift_right_by(2) == 0b1110_0100
2075```
2076In some languages `shift_right_by` is implemented as a binary operator `>>>`.
2077
2078shift_right_zf_by : Int a, U8 -> Int a
2079
2080Description:
2081Bitwise logical right shift of a number by another
2082
2083The most significant bits always become 0. This means that shifting right is
2084like dividing by factors of two for unsigned integers.
2085```roc
2086shift_right_zf_by(0b0010_1000, 2) == 0b0000_1010
2087
20880b0010_1000 |> shift_right_zf_by(2) == 0b0000_1010
2089
20900b1001_0000 |> shift_right_zf_by(2) == 0b0010_0100
2091```
2092In some languages `shift_right_zf_by` is implemented as a binary operator `>>`.
2093
2094round : Frac * -> Int *
2095
2096Description:
2097Round off the given fraction to the nearest integer.
2098
2099floor : Frac * -> Int *
2100
2101ceiling : Frac * -> Int *
2102
2103pow : Frac a, Frac a -> Frac a
2104
2105Description:
2106Raises a [Frac] to the power of another [Frac].
2107
2108For an [Int] alternative to this function, see [Num.pow_int]
2109
2110pow_int : Int a, Int a -> Int a
2111
2112Description:
2113Raises an integer to the power of another, by multiplying the integer by
2114itself the given number of times.
2115
2116This process is known as [exponentiation by squaring](https://en.wikipedia.org/wiki/Exponentiation_by_squaring).
2117
2118For a [Frac] alternative to this function, which supports negative exponents,
2119see #Num.pow.
2120
2121## Warning
2122
2123It is very easy for this function to produce an answer
2124so large it causes an overflow.
2125
2126count_leading_zero_bits : Int a -> U8
2127
2128Description:
2129Counts the number of most-significant (leading in a big-Endian sense) zeroes in an integer.
2130
2131```roc
2132Num.count_leading_zero_bits(0b0001_1100u8)
2133
21343
2135
2136Num.count_leading_zero_bits(0b0000_0000u8)
2137
21388
2139```
2140
2141count_trailing_zero_bits : Int a -> U8
2142
2143Description:
2144Counts the number of least-significant (trailing in a big-Endian sense) zeroes in an integer.
2145
2146```roc
2147Num.count_trailing_zero_bits(0b0001_1100u8)
2148
21492
2150
2151Num.count_trailing_zero_bits(0b0000_0000u8)
2152
21538
2154```
2155
2156count_one_bits : Int a -> U8
2157
2158Description:
2159Counts the number of set bits in an integer.
2160
2161```roc
2162Num.count_one_bits(0b0001_1100u8)
2163
21643
2165
2166Num.count_one_bits(0b0000_0000u8)
2167
21680
2169```
2170
2171add_wrap : Int range, Int range -> Int range
2172
2173add_saturated : Num a, Num a -> Num a
2174
2175Description:
2176Adds two numbers, clamping on the maximum representable number rather than
2177overflowing.
2178
2179This is the same as [Num.add] except for the saturating behavior if the
2180addition is to overflow.
2181For example, if `x : U8` is 200 and `y : U8` is 100, `add_saturated x y` will
2182yield 255, the maximum value of a `U8`.
2183
2184add_checked : Num a, Num a -> Result (Num a) [Overflow]
2185
2186Description:
2187Adds two numbers and checks for overflow.
2188
2189This is the same as [Num.add] except if the operation overflows, instead of
2190panicking or returning ∞ or -∞, it will return `Err Overflow`.
2191
2192sub_wrap : Int range, Int range -> Int range
2193
2194sub_saturated : Num a, Num a -> Num a
2195
2196Description:
2197Subtracts two numbers, clamping on the minimum representable number rather
2198than overflowing.
2199
2200This is the same as [Num.sub] except for the saturating behavior if the
2201subtraction is to overflow.
2202For example, if `x : U8` is 10 and `y : U8` is 20, `sub_saturated x y` will
2203yield 0, the minimum value of a `U8`.
2204
2205sub_checked : Num a, Num a -> Result (Num a) [Overflow]
2206
2207Description:
2208Subtracts two numbers and checks for overflow.
2209
2210This is the same as [Num.sub] except if the operation overflows, instead of
2211panicking or returning ∞ or -∞, it will return `Err Overflow`.
2212
2213mul_wrap : Int range, Int range -> Int range
2214
2215mul_saturated : Num a, Num a -> Num a
2216
2217Description:
2218Multiplies two numbers, clamping on the maximum representable number rather than
2219overflowing.
2220
2221This is the same as [Num.mul] except for the saturating behavior if the
2222addition is to overflow.
2223
2224mul_checked : Num a, Num a -> Result (Num a) [Overflow]
2225
2226Description:
2227Multiplies two numbers and checks for overflow.
2228
2229This is the same as [Num.mul] except if the operation overflows, instead of
2230panicking or returning ∞ or -∞, it will return `Err Overflow`.
2231
2232min_i8 : I8
2233
2234Description:
2235Returns the lowest number that can be stored in an [I8] without underflowing
2236its available memory and crashing.
2237
2238For reference, this number is `-128`.
2239
2240Note that the positive version of this number is larger than [Num.max_i8],
2241which means if you call [Num.abs] on [Num.min_i8], it will overflow and crash!
2242
2243max_i8 : I8
2244
2245Description:
2246Returns the highest number that can be stored in an [I8] without overflowing
2247its available memory and crashing.
2248
2249For reference, this number is `127`.
2250
2251Note that this is smaller than the positive version of [Num.min_i8],
2252which means if you call [Num.abs] on [Num.min_i8], it will overflow and crash!
2253
2254min_u8 : U8
2255
2256Description:
2257Returns the lowest number that can be stored in a [U8] without underflowing
2258its available memory and crashing.
2259
2260For reference, this number is zero, because [U8] is
2261[unsigned](https://en.wikipedia.org/wiki/Signed_number_representations),
2262and zero is the lowest unsigned number.
2263Unsigned numbers cannot be negative.
2264
2265max_u8 : U8
2266
2267Description:
2268Returns the highest number that can be stored in a [U8] without overflowing
2269its available memory and crashing.
2270
2271For reference, this number is `255`.
2272
2273min_i16 : I16
2274
2275Description:
2276Returns the lowest number that can be stored in an [I16] without underflowing
2277its available memory and crashing.
2278
2279For reference, this number is `-32_768`.
2280
2281Note that the positive version of this number is larger than [Num.max_i16],
2282which means if you call [Num.abs] on [Num.min_i16], it will overflow and crash!
2283
2284max_i16 : I16
2285
2286Description:
2287Returns the highest number that can be stored in an [I16] without overflowing
2288its available memory and crashing.
2289
2290For reference, this number is `32_767`.
2291
2292Note that this is smaller than the positive version of [Num.min_i16],
2293which means if you call [Num.abs] on [Num.min_i16], it will overflow and crash!
2294
2295min_u16 : U16
2296
2297Description:
2298Returns the lowest number that can be stored in a [U16] without underflowing
2299its available memory and crashing.
2300
2301For reference, this number is zero, because [U16] is
2302[unsigned](https://en.wikipedia.org/wiki/Signed_number_representations),
2303and zero is the lowest unsigned number.
2304Unsigned numbers cannot be negative.
2305
2306max_u16 : U16
2307
2308Description:
2309Returns the highest number that can be stored in a [U16] without overflowing
2310its available memory and crashing.
2311
2312For reference, this number is `65_535`.
2313
2314min_i32 : I32
2315
2316Description:
2317Returns the lowest number that can be stored in an [I32] without underflowing
2318its available memory and crashing.
2319
2320For reference, this number is `-2_147_483_648`.
2321
2322Note that the positive version of this number is larger than [Num.max_i32],
2323which means if you call [Num.abs] on [Num.min_i32], it will overflow and crash!
2324
2325max_i32 : I32
2326
2327Description:
2328Returns the highest number that can be stored in an [I32] without overflowing
2329its available memory and crashing.
2330
2331For reference, this number is `2_147_483_647`,
2332which is over 2 million.
2333
2334Note that this is smaller than the positive version of [Num.min_i32],
2335which means if you call [Num.abs] on [Num.min_i32], it will overflow and crash!
2336
2337min_u32 : U32
2338
2339Description:
2340Returns the lowest number that can be stored in a [U32] without underflowing
2341its available memory and crashing.
2342
2343For reference, this number is zero, because [U32] is
2344[unsigned](https://en.wikipedia.org/wiki/Signed_number_representations),
2345and zero is the lowest unsigned number.
2346Unsigned numbers cannot be negative.
2347
2348max_u32 : U32
2349
2350Description:
2351Returns the highest number that can be stored in a [U32] without overflowing
2352its available memory and crashing.
2353
2354For reference, this number is `4_294_967_295`.
2355
2356min_i64 : I64
2357
2358Description:
2359Returns the lowest number that can be stored in an [I64] without underflowing
2360its available memory and crashing.
2361
2362For reference, this number is `-9_223_372_036_854_775_808`,
2363which is under 9 quintillion.
2364
2365Note that the positive version of this number is larger than [Num.max_i64],
2366which means if you call [Num.abs] on [Num.min_i64], it will overflow and crash!
2367
2368max_i64 : I64
2369
2370Description:
2371Returns the highest number that can be stored in an [I64] without overflowing
2372its available memory and crashing.
2373
2374For reference, this number is `9_223_372_036_854_775_807`,
2375which is over 9 quintillion.
2376
2377Note that this is smaller than the positive version of [Num.min_i64],
2378which means if you call [Num.abs] on [Num.min_i64], it will overflow and crash!
2379
2380min_u64 : U64
2381
2382Description:
2383Returns the lowest number that can be stored in a [U64] without underflowing
2384its available memory and crashing.
2385
2386For reference, this number is zero, because [U64] is
2387[unsigned](https://en.wikipedia.org/wiki/Signed_number_representations),
2388and zero is the lowest unsigned number.
2389Unsigned numbers cannot be negative.
2390
2391max_u64 : U64
2392
2393Description:
2394Returns the highest number that can be stored in a [U64] without overflowing
2395its available memory and crashing.
2396
2397For reference, this number is `18_446_744_073_709_551_615`,
2398which is over 18 quintillion.
2399
2400min_i128 : I128
2401
2402Description:
2403Returns the lowest number that can be stored in an [I128] without underflowing
2404its available memory and crashing.
2405
2406For reference, this number is `-170_141_183_460_469_231_731_687_303_715_884_105_728`.
2407which is under 170 undecillion.
2408
2409Note that the positive version of this number is larger than [Num.max_i128],
2410which means if you call [Num.abs] on [Num.min_i128], it will overflow and crash!
2411
2412max_i128 : I128
2413
2414Description:
2415Returns the highest number that can be stored in an [I128] without overflowing
2416its available memory and crashing.
2417
2418For reference, this number is `170_141_183_460_469_231_731_687_303_715_884_105_727`,
2419which is over 170 undecillion.
2420
2421Note that this is smaller than the positive version of [Num.min_i128],
2422which means if you call [Num.abs] on [Num.min_i128], it will overflow and crash!
2423
2424min_u128 : U128
2425
2426Description:
2427Returns the lowest number that can be stored in a [U128] without underflowing
2428its available memory and crashing.
2429
2430For reference, this number is zero, because [U128] is
2431[unsigned](https://en.wikipedia.org/wiki/Signed_number_representations),
2432and zero is the lowest unsigned number.
2433Unsigned numbers cannot be negative.
2434
2435max_u128 : U128
2436
2437Description:
2438Returns the highest number that can be stored in a [U128] without overflowing
2439its available memory and crashing.
2440
2441For reference, this number is `340_282_366_920_938_463_463_374_607_431_768_211_455`,
2442which is over 340 undecillion.
2443
2444min_f32 : F32
2445
2446max_f32 : F32
2447
2448min_f64 : F64
2449
2450max_f64 : F64
2451
2452to_i8 : Int * -> I8
2453
2454Description:
2455Converts an [Int] to an [I8]. If the given number can't be precisely represented in an [I8],
2456the returned number may be different from the given number.
2457
2458to_i16 : Int * -> I16
2459
2460to_i32 : Int * -> I32
2461
2462to_i64 : Int * -> I64
2463
2464to_i128 : Int * -> I128
2465
2466to_u8 : Int * -> U8
2467
2468to_u16 : Int * -> U16
2469
2470to_u32 : Int * -> U32
2471
2472to_u64 : Int * -> U64
2473
2474to_u128 : Int * -> U128
2475
2476to_f32 : Num * -> F32
2477
2478Description:
2479Converts a [Num] to an [F32]. If the given number can't be precisely represented in an [F32],
2480the returned number may be different from the given number.
2481
2482to_f64 : Num * -> F64
2483
2484Description:
2485Converts a [Num] to an [F64]. If the given number can't be precisely represented in an [F64],
2486the returned number may be different from the given number.
2487
2488to_i8_checked : Int * -> Result I8 [OutOfBounds]
2489
2490Description:
2491Converts a [Int] to an [I8].
2492If the given integer can't be precisely represented in an [I8], returns
2493`Err OutOfBounds`.
2494
2495to_i16_checked : Int * -> Result I16 [OutOfBounds]
2496
2497to_i32_checked : Int * -> Result I32 [OutOfBounds]
2498
2499to_i64_checked : Int * -> Result I64 [OutOfBounds]
2500
2501to_i128_checked : Int * -> Result I128 [OutOfBounds]
2502
2503to_u8_checked : Int * -> Result U8 [OutOfBounds]
2504
2505to_u16_checked : Int * -> Result U16 [OutOfBounds]
2506
2507to_u32_checked : Int * -> Result U32 [OutOfBounds]
2508
2509to_u64_checked : Int * -> Result U64 [OutOfBounds]
2510
2511to_u128_checked : Int * -> Result U128 [OutOfBounds]
2512
2513to_f32_checked : Num * -> Result F32 [OutOfBounds]
2514
2515to_f64_checked : Num * -> Result F64 [OutOfBounds]
2516
2517without_decimal_point : Dec -> I128
2518
2519Description:
2520Turns a [Dec] into its [I128] representation by removing the decimal point.
2521This is equivalent to multiplying the [Dec] by 10^18.
2522
2523with_decimal_point : I128 -> Dec
2524
2525Description:
2526Turns a [I128] into the coresponding [Dec] by adding the decimal point.
2527This is equivalent to dividing the [I128] by 10^18.
2528
2529f32_to_parts : F32 -> { sign : Bool, exponent : U8, fraction : U32 }
2530
2531Description:
2532Splits a [F32] into its components according to IEEE 754 standard.
2533
2534This function is deprecated due to common pitfalls when working with float components
2535using Roc’s fixed-size integer types. Please use [Num.f32_to_bits] instead and extract the
2536[IEEE 754 parts](https://en.wikipedia.org/wiki/Single-precision_floating-point_format#IEEE_754_standard:_binary32)
2537manually from the resulting [U32].
2538
2539f64_to_parts : F64 -> { sign : Bool, exponent : U16, fraction : U64 }
2540
2541Description:
2542Splits a [F64] into its components according to IEEE 754 standard.
2543
2544This function is deprecated due to common pitfalls when working with float components
2545using Roc’s fixed-size integer types. Please use [Num.f64_to_bits] instead and extract the
2546[IEEE 754 parts](https://en.wikipedia.org/wiki/Double-precision_floating-point_format#IEEE_754_double-precision_binary_floating-point_format:_binary64)
2547manually from the resulting [U64].
2548
2549f32_from_parts : { sign : Bool, exponent : U8, fraction : U32 } -> F32
2550
2551Description:
2552Combine parts of a [F32] according to IEEE 754 standard.
2553The fraction should not be bigger than 0x007F_FFFF, any bigger value will be truncated.
2554
2555This function is deprecated due to common pitfalls when working with float components
2556using Roc’s fixed-size integer types. Please combine the
2557[IEEE 754 parts](https://en.wikipedia.org/wiki/Single-precision_floating-point_format#IEEE_754_standard:_binary32)
2558manually into a [U32] and use [Num.f32_from_bits] to create the [F32] instead.
2559
2560f64_from_parts : { sign : Bool, exponent : U16, fraction : U64 } -> F64
2561
2562Description:
2563Combine parts of a [F64] according to IEEE 754 standard.
2564The fraction should not be bigger than 0x000F_FFFF_FFFF_FFFF, any bigger value will be truncated.
2565The exponent should not be bigger than 0x07FF, any bigger value will be truncated.
2566
2567This function is deprecated due to common pitfalls when working with float components
2568using Roc’s fixed-size integer types. Please combine the
2569[IEEE 754 parts](https://en.wikipedia.org/wiki/Double-precision_floating-point_format#IEEE_754_double-precision_binary_floating-point_format:_binary64)
2570manually into a [U64] and use [Num.f64_from_bits] to create the [F64] instead.
2571
2572f32_to_bits : F32 -> U32
2573
2574Description:
2575Returns a [U32] containing the raw bits of a [F32], as defined by the IEEE 754 standard.
2576
2577f64_to_bits : F64 -> U64
2578
2579Description:
2580Returns a [U64] containing the raw bits of a [F64], as defined by the IEEE 754 standard.
2581
2582dec_to_bits : Dec -> U128
2583
2584Description:
2585Returns a [U128] containing the raw bits of a [Dec], which corresponds to the raw bits
2586of its [I128] representation.
2587
2588f32_from_bits : U32 -> F32
2589
2590Description:
2591Interprets a [U32] as the binary representation of a 32-bit floating-point value according
2592to the IEEE 754 standard and returns the corresponding [F32].
2593
2594f64_from_bits : U64 -> F64
2595
2596Description:
2597Interprets a [U64] as the binary representation of a 64-bit floating-point value according
2598to the IEEE 754 standard and returns the corresponding [F64].
2599
2600dec_from_bits : U128 -> Dec
2601
2602Description:
2603Interprets a [U128] as the raw bits of the internal [I128] representation of a fixed-point
2604decimal value and returns the corresponding [Dec].
2605
2606from_bool : Bool -> Num *
2607
2608Description:
2609Convert a `Bool` to a `Num`
2610```roc
2611expect Num.from_bool(Bool.true) == 1
2612expect Num.from_bool(Bool.false) == 0
2613```
2614
2615nan_f32 : F32
2616
2617Description:
2618The value for not-a-number for a [F32] according to the IEEE 754 standard.
2619
2620nan_f64 : F64
2621
2622Description:
2623The value for not-a-number for a [F64] according to the IEEE 754 standard.
2624
2625infinity_f32 : F32
2626
2627Description:
2628The value for infinity for a [F32] according to the IEEE 754 standard.
2629
2630infinity_f64 : F64
2631
2632Description:
2633The value for infinity for a [F64] according to the IEEE 754 standard.
2634
2635### Bool
2636
2637Eq : implements
2638 is_eq : a, a -> Bool
2639 where a implements Eq
2640
2641Description:
2642Defines a type that can be compared for total equality.
2643
2644Total equality means that all values of the type can be compared to each
2645other, and two values `a`, `b` are identical if and only if `is_eq(a, b)` is
2646`Bool.true`.
2647
2648Not all types support total equality. For example, [`F32`](Num#F32) and [`F64`](Num#F64) can
2649be a `NaN` ([Not a Number](https://en.wikipedia.org/wiki/NaN)), and the
2650[IEEE-754](https://en.wikipedia.org/wiki/IEEE_754) floating point standard
2651specifies that two `NaN`s are not equal.
2652
2653Description:
2654Represents the boolean true and false using an opaque type.
2655`Bool` implements the `Eq` ability.
2656
2657true : Bool
2658
2659Description:
2660The boolean true value.
2661
2662false : Bool
2663
2664Description:
2665The boolean false value.
2666
2667not : Bool -> Bool
2668
2669Description:
2670Returns `Bool.false` when given `Bool.true`, and vice versa. This is
2671equivalent to the logic [NOT](https://en.wikipedia.org/wiki/Negation)
2672gate. The operator `!` can also be used as shorthand for `Bool.not`.
2673```roc
2674expect Bool.not(Bool.false) == Bool.true
2675expect !Bool.false == Bool.true
2676```
2677
2678is_not_eq : a, a -> Bool where a implements Eq
2679
2680Description:
2681This will call the function `Bool.is_eq` on the inputs, and then `Bool.not`
2682on the result. The is equivalent to the logic
2683[XOR](https://en.wikipedia.org/wiki/Exclusive_or) gate. The infix operator
2684`!=` can also be used as shorthand for `Bool.is_not_eq`.
2685
2686**Note** that `is_not_eq` does not accept arguments whose types contain
2687functions.
2688```roc
2689expect Bool.is_not_eq(Bool.false, Bool.true) == Bool.true
2690expect (Bool.false != Bool.false) == Bool.false
2691expect "Apples" != "Oranges"
2692```
2693
2694### Result
2695
2696Result : [ Ok ok, Err err ]
2697
2698Description:
2699The result of an operation that could fail: either the operation went
2700okay, or else there was an error of some sort.
2701
2702is_ok : Result ok err -> Bool
2703
2704Description:
2705Returns `Bool.true` if the result indicates a success, else returns `Bool.false`.
2706```roc
2707Result.is_ok(Ok(5))
2708```
2709
2710is_err : Result ok err -> Bool
2711
2712Description:
2713Returns `Bool.true` if the result indicates a failure, else returns `Bool.false`.
2714```roc
2715Result.is_err(Err("uh oh"))
2716```
2717
2718with_default : Result ok err, ok -> ok
2719
2720Description:
2721If the result is `Ok`, returns the value it holds. Otherwise, returns
2722the given default value.
2723
2724Note: This function should be used sparingly, because it hides that an error
2725happened, which will make debugging harder. Prefer using `?` to forward errors or
2726handle them explicitly with `when`.
2727```roc
2728Result.with_default(Err("uh oh"), 42) # = 42
2729
2730Result.with_default(Ok(7), 42) # = 7
2731```
2732
2733map_ok : Result a err, (a -> b) -> Result b err
2734
2735Description:
2736If the result is `Ok`, transforms the value it holds by running a conversion
2737function on it. Then returns a new `Ok` holding the transformed value. If the
2738result is `Err`, this has no effect. Use [map_err] to transform an `Err`.
2739```roc
2740Result.map_ok(Ok(12), Num.neg) # = Ok(-12)
2741
2742Result.map_ok(Err("yipes!"), Num.neg) # = Err("yipes!")
2743```
2744Functions like `map` are common in Roc; see for example [List.map],
2745`Set.map`, and `Dict.map`.
2746
2747map_err : Result ok a, (a -> b) -> Result ok b
2748
2749Description:
2750If the result is `Err`, transforms the value it holds by running a conversion
2751function on it. Then returns a new `Err` holding the transformed value. If
2752the result is `Ok`, this has no effect. Use [map_ok] to transform an `Ok`.
2753```roc
2754List.last([]) |> Result.map_err(|_| ProvidedListIsEmpty) # = Err(ProvidedListIsEmpty)
2755
2756List.last([4]) |> Result.map_err(|_| ProvidedListIsEmpty) # = Ok(4)
2757```
2758
2759on_err : Result a err, (err -> Result a other_err) -> Result a other_err
2760
2761Description:
2762If the result is `Err`, transforms the entire result by running a conversion
2763function on the value the `Err` holds. Then returns that new result. If the
2764result is `Ok`, this has no effect. Use `?` or [try] to transform an `Ok`.
2765```roc
2766Result.on_err(Ok(10), Str.to_u64) # = Ok(10)
2767
2768Result.on_err(Err("42"), Str.to_u64) # = Ok(42)
2769
2770Result.on_err(Err("string"), Str.to_u64) # = Err(InvalidNumStr)
2771```
2772
2773on_err! : Result a err, (err => Result a other_err) => Result a other_err
2774
2775Description:
2776Like [on_err], but it allows the transformation function to produce effects.
2777
2778```roc
2779Result.on_err(
2780 Err("missing user"),
2781 |msg|
2782 Stdout.line!("ERROR: ${msg}")?
2783 Err(msg)
2784)
2785```
2786
2787map_both : Result ok1 err1, (ok1 -> ok2), (err1 -> err2) -> Result ok2 err2
2788
2789Description:
2790Maps both the `Ok` and `Err` values of a `Result` to new values.
2791
2792map2 : Result a err, Result b err, (a, b -> c) -> Result c err
2793
2794Description:
2795Maps the `Ok` values of two `Result`s to a new value using a given transformation,
2796or returns the first `Err` value encountered.
2797
2798try : Result a err, (a -> Result b err) -> Result b err
2799
2800Description:
2801If the result is `Ok`, transforms the entire result by running a conversion
2802function on the value the `Ok` holds. Then returns that new result. If the
2803result is `Err`, this has no effect.
2804
2805We recommend using `?` instead of `try`, it makes the code easier to read.
2806```roc
2807Result.try(Ok(-1), (|num| if num < 0 then Err("negative!") else Ok(-num))) # = Err("negative!")
2808
2809Result.try(Err("yipes!"), (|num| -> if num < 0 then Err("negative!") else Ok(-num))) # = Err("yipes!")
2810```
2811
2812### List
2813
2814is_empty : List * -> Bool
2815
2816Description:
2817 Check if the list is empty.
2818```roc
2819List.is_empty([1, 2, 3])
2820
2821List.is_empty([])
2822```
2823
2824get : List a, U64 -> Result a [OutOfBounds]
2825
2826Description:
2827Returns an element from a list at the given index.
2828
2829Returns `Err OutOfBounds` if the given index exceeds the List's length
2830```roc
2831expect List.get([100, 200, 300], 1) == Ok(200)
2832expect List.get([100, 200, 300], 5) == Err(OutOfBounds)
2833```
2834
2835replace : List a, U64, a -> { list : List a, value : a }
2836
2837set : List a, U64, a -> List a
2838
2839Description:
2840Replaces the element at the given index with a replacement.
2841```roc
2842List.set(["a", "b", "c"], 1, "B")
2843```
2844If the given index is outside the bounds of the list, returns the original
2845list unmodified.
2846
2847To drop the element at a given index, instead of replacing it, see [List.drop_at].
2848
2849update : List a, U64, (a -> a) -> List a
2850
2851Description:
2852Updates the element at the given index with the given function.
2853```roc
2854List.update([1, 2, 3], 1, (|x| x + 1))
2855```
2856If the given index is outside the bounds of the list, returns the original
2857list unmodified.
2858
2859To replace the element at a given index, instead of updating based on the current value,
2860see [List.set] and [List.replace]
2861
2862append : List a, a -> List a
2863
2864Description:
2865Add a single element to the end of a list.
2866```roc
2867List.append([1, 2, 3], 4)
2868
2869[0, 1, 2]
2870 |> List.append(3)
2871```
2872
2873append_if_ok : List a, Result a * -> List a
2874
2875Description:
2876If the given [Result] is `Ok`, add it to the end of a list.
2877Otherwise, return the list unmodified.
2878
2879```roc
2880List.append_if_ok([1, 2, 3], Ok(4))
2881
2882[0, 1, 2]
2883 |> List.append_if_ok(Err(3))
2884```
2885
2886prepend : List a, a -> List a
2887
2888Description:
2889Add a single element to the beginning of a list.
2890```roc
2891List.prepend([1, 2, 3], 0)
2892
2893[2, 3, 4]
2894 |> List.prepend(1)
2895```
2896
2897prepend_if_ok : List a, Result a * -> List a
2898
2899Description:
2900If the given [Result] is `Ok`, add it to the beginning of a list.
2901Otherwise, return the list unmodified.
2902
2903```roc
2904List.prepend([1, 2, 3], Ok(0))
2905
2906[2, 3, 4]
2907 |> List.prepend(Err(1))
2908```
2909
2910len : List * -> U64
2911
2912Description:
2913Returns the length of the list - the number of elements it contains.
2914
2915One [List] can store up to `Num.max_i64` elements on 64-bit targets and `Num.max_i32` on 32-bit targets like wasm.
2916This means the #U64 this function returns can always be safely converted to #I64 or #I32, depending on the target.
2917
2918with_capacity : U64 -> List *
2919
2920Description:
2921Create a list with space for at least capacity elements
2922
2923reserve : List a, U64 -> List a
2924
2925Description:
2926Enlarge the list for at least capacity additional elements
2927
2928release_excess_capacity : List a -> List a
2929
2930Description:
2931Shrink the memory footprint of a list such that it's capacity and length are equal.
2932Note: This will also convert seamless slices to regular lists.
2933
2934concat : List a, List a -> List a
2935
2936Description:
2937Put two lists together.
2938```roc
2939List.concat([1, 2, 3], [4, 5])
2940
2941[0, 1, 2]
2942 |> List.concat([3, 4])
2943```
2944
2945last : List a -> Result a [ListWasEmpty]
2946
2947Description:
2948Returns the last element in the list, or `ListWasEmpty` if it was empty.
2949```roc
2950expect List.last([1, 2, 3]) == Ok(3)
2951expect List.last([]) == Err(ListWasEmpty)
2952```
2953
2954single : a -> List a
2955
2956Description:
2957A list with a single element in it.
2958
2959This is useful in pipelines, like so:
2960```roc
2961websites =
2962 Str.concat(domain, ".com")
2963 |> List.single
2964```
2965
2966repeat : a, U64 -> List a
2967
2968Description:
2969Returns a list with the given length, where every element is the given value.
2970
2971reverse : List a -> List a
2972
2973Description:
2974Returns the list with its elements reversed.
2975```roc
2976expect List.reverse([1, 2, 3]) == [3, 2, 1]
2977```
2978
2979join : List (List a) -> List a
2980
2981Description:
2982Join the given lists together into one list.
2983```roc
2984expect List.join([[1], [2, 3], [], [4, 5]]) == [1, 2, 3, 4, 5]
2985expect List.join([[], []]) == []
2986expect List.join([]) == []
2987```
2988
2989contains : List a, a -> Bool where a implements Eq
2990
2991walk : List elem, state, (state, elem -> state) -> state
2992
2993Description:
2994Build a value using each element in the list.
2995
2996Starting with a given `state` value, this walks through each element in the
2997list from first to last, running a given `step` function on that element
2998which updates the `state`. It returns the final `state` at the end.
2999
3000You can use it in a pipeline:
3001```roc
3002[2, 4, 8]
3003 |> List.walk(0, Num.add)
3004```
3005This returns 14 because:
3006* `state` starts at 0
3007* Each `step` runs `Num.add(state, elem)`, and the return value becomes the new `state`.
3008
3009Here is a table of how `state` changes as [List.walk] walks over the elements
3010`[2, 4, 8]` using [Num.add] as its `step` function to determine the next `state`.
3011
3012state | elem | Num.add state elem
3013:---: | :---: | :----------------:
30140 | |
30150 | 2 | 2
30162 | 4 | 6
30176 | 8 | 14
3018
3019The following returns -6:
3020```roc
3021[1, 2, 3]
3022 |> List.walk(0, Num.sub)
3023```
3024Note that in other languages, `walk` is sometimes called `reduce`,
3025`fold`, `fold_left`, or `foldl`.
3026
3027walk_with_index : List elem, state, (state, elem, U64 -> state) -> state
3028
3029Description:
3030Like [walk], but at each step the function also receives the index of the current element.
3031
3032walk_with_index_until : List elem, state, (state, elem, U64 -> [ Continue state, Break state ]) -> state
3033
3034Description:
3035Like [walk_until], but at each step the function also receives the index of the current element.
3036
3037walk_backwards : List elem, state, (state, elem -> state) -> state
3038
3039Description:
3040Note that in other languages, `walk_backwards` is sometimes called `reduce_right`,
3041`fold`, `fold_right`, or `foldr`.
3042
3043walk_until : List elem, state, (state, elem -> [ Continue state, Break state ]) -> state
3044
3045Description:
3046Same as [List.walk], except you can stop walking early.
3047
3048## Performance Details
3049
3050Compared to [List.walk], this can potentially visit fewer elements (which can
3051improve performance) at the cost of making each step take longer.
3052However, the added cost to each step is extremely small, and can easily
3053be outweighed if it results in skipping even a small number of elements.
3054
3055As such, it is typically better for performance to use this over [List.walk]
3056if returning `Break` earlier than the last element is expected to be common.
3057
3058walk_backwards_until : List elem, state, (state, elem -> [ Continue state, Break state ]) -> state
3059
3060Description:
3061Same as [List.walk_until], but does it from the end of the list instead.
3062
3063walk_from : List elem, U64, state, (state, elem -> state) -> state
3064
3065Description:
3066Walks to the end of the list from a specified starting index
3067
3068walk_from_until : List elem, U64, state, (state, elem -> [ Continue state, Break state ]) -> state
3069
3070Description:
3071A combination of [List.walk_from] and [List.walk_until]
3072
3073sum : List (Num a) -> Num a
3074
3075product : List (Num a) -> Num a
3076
3077any : List a, (a -> Bool) -> Bool
3078
3079Description:
3080Run the given predicate on each element of the list, returning `Bool.true` if
3081any of the elements satisfy it.
3082
3083all : List a, (a -> Bool) -> Bool
3084
3085Description:
3086Run the given predicate on each element of the list, returning `Bool.true` if
3087all of the elements satisfy it.
3088
3089keep_if : List a, (a -> Bool) -> List a
3090
3091Description:
3092Run the given function on each element of a list, and return all the
3093elements for which the function returned `Bool.true`.
3094```roc
3095List.keep_if([1, 2, 3, 4], (|num| num > 2))
3096```
3097## Performance Details
3098
3099[List.keep_if] always returns a list that takes up exactly the same amount
3100of memory as the original, even if its length decreases. This is because it
3101can't know in advance exactly how much space it will need, and if it guesses a
3102length that's too low, it would have to re-allocate.
3103
3104(If you want to do an operation like this which reduces the memory footprint
3105of the resulting list, you can do two passes over the list with [List.walk] - one
3106to calculate the precise new size, and another to populate the new list.)
3107
3108If given a unique list, [List.keep_if] will mutate it in place to assemble the appropriate list.
3109If that happens, this function will not allocate any new memory on the heap.
3110If all elements in the list end up being kept, Roc will return the original
3111list unaltered.
3112
3113
3114keep_if_try! : List a, (a => Result Bool err) => Result (List a) err
3115
3116Description:
3117Run an effectful function that returns a [Result] on each element of a list, and return all the
3118elements for which the function returned `Ok(Bool.true)`.
3119```roc
3120dirs_only = List.keep_if_try!(path_list, Path.is_dir!)?
3121```
3122
3123
3124drop_if : List a, (a -> Bool) -> List a
3125
3126Description:
3127Run the given function on each element of a list, and return all the
3128elements for which the function returned `Bool.false`.
3129```roc
3130List.drop_if([1, 2, 3, 4], (|num| num > 2))
3131```
3132## Performance Details
3133
3134`List.drop_if` has the same performance characteristics as [List.keep_if].
3135See its documentation for details on those characteristics!
3136
3137count_if : List a, (a -> Bool) -> U64
3138
3139Description:
3140Run the given function on each element of a list, and return the
3141number of elements for which the function returned `Bool.true`.
3142```roc
3143expect List.count_if([1, -2, -3], Num.is_negative) == 2
3144expect List.count_if([1, 2, 3], (|num| num > 1)) == 2
3145```
3146
3147keep_oks : List before, (before -> Result after *) -> List after
3148
3149Description:
3150This works like [List.map], except only the transformed values that are
3151wrapped in `Ok` are kept. Any that are wrapped in `Err` are dropped.
3152```roc
3153expect List.keep_oks(["1", "Two", "23", "Bird"], Str.to_i32) == [1, 23]
3154
3155expect List.keep_oks([["a", "b"], [], ["c", "d", "e"], [] ], List.first) == ["a", "c"]
3156
3157fn = |str| if Str.is_empty(str) then Err(StrWasEmpty) else Ok(str)
3158expect List.keep_oks(["", "a", "bc", "", "d", "ef", ""], fn) == ["a", "bc", "d", "ef"]
3159```
3160
3161keep_errs : List before, (before -> Result * after) -> List after
3162
3163Description:
3164This works like [List.map], except only the transformed values that are
3165wrapped in `Err` are kept. Any that are wrapped in `Ok` are dropped.
3166```roc
3167List.keep_errs([["a", "b"], [], [], ["c", "d", "e"]], List.last)
3168
3169fn = |str| if Str.is_empty(str) then Err(StrWasEmpty) else Okd(Str.len(str))
3170
3171List.keep_errs(["", "a", "bc", "", "d", "ef", ""], fn)
3172```
3173
3174map : List a, (a -> b) -> List b
3175
3176Description:
3177Convert each element in the list to something new, by calling a conversion
3178function on each of them. Then return a new list of the converted values.
3179```roc
3180expect List.map([1, 2, 3], (|num| num + 1)) == [2, 3, 4]
3181
3182expect List.map(["", "a", "bc"], Str.is_empty) == [Bool.true, Bool.false, Bool.false]
3183```
3184
3185map2 : List a, List b, (a, b -> c) -> List c
3186
3187Description:
3188Run a transformation function on the first element of each list,
3189and use that as the first element in the returned list.
3190Repeat until a list runs out of elements.
3191
3192Some languages have a function named `zip`, which does something similar to
3193calling [List.map2] passing two lists and `Pair`:
3194```roc
3195zipped = List.map2(["a", "b", "c"], [1, 2, 3], Pair)
3196```
3197
3198map3 : List a, List b, List c, (a, b, c -> d) -> List d
3199
3200Description:
3201Run a transformation function on the first element of each list,
3202and use that as the first element in the returned list.
3203Repeat until a list runs out of elements.
3204
3205map4 : List a, List b, List c, List d, (a, b, c, d -> e) -> List e
3206
3207Description:
3208Run a transformation function on the first element of each list,
3209and use that as the first element in the returned list.
3210Repeat until a list runs out of elements.
3211
3212map_with_index : List a, (a, U64 -> b) -> List b
3213
3214Description:
3215This works like [List.map], except it also passes the index
3216of the element to the conversion function.
3217```roc
3218expect List.map_with_index([10, 20, 30], (|num, index| num + index)) == [10, 21, 32]
3219```
3220
3221Description:
3222Returns a list of all the integers between `start` and `end`.
3223
3224To include the `start` and `end` integers themselves, use `At` like so:
3225```roc
3226List.range({ start: At 2, end: At 5 }) == [2, 3, 4, 5]
3227```
3228To exclude them, use `After` and `Before`, like so:
3229```roc
3230List.range({ start: After 2, end: Before 5 }) == [3, 4]
3231```
3232You can have the list end at a certain length rather than a certain integer:
3233```roc
3234List.range({ start: At 6, end: Length 4 }) == [6, 7, 8, 9]
3235```
3236If `step` is specified, each integer increases by that much. (`step: 1` is the default.)
3237```roc
3238List.range({ start: After 0, end: Before 9, step: 3 }) == [3, 6]
3239```
3240List.range will also generate a reversed list if step is negative or end comes before start:
3241```roc
3242List.range({ start: At 5, end: At 2 }) == [5, 4, 3, 2]
3243```
3244All of these options are compatible with the others. For example, you can use `At` or `After`
3245with `start` regardless of what `end` and `step` are set to.
3246
3247sort_with : List a, (a, a -> [ LT, EQ, GT ]) -> List a
3248
3249Description:
3250Sort with a custom comparison function
3251
3252sort_asc : List (Num a) -> List (Num a)
3253
3254Description:
3255Sorts a list of numbers in ascending order (lowest to highest).
3256
3257To sort in descending order (highest to lowest), use [List.sort_desc] instead.
3258
3259sort_desc : List (Num a) -> List (Num a)
3260
3261Description:
3262Sorts a list of numbers in descending order (highest to lowest).
3263
3264To sort in ascending order (lowest to highest), use [List.sort_asc] instead.
3265
3266swap : List a, U64, U64 -> List a
3267
3268first : List a -> Result a [ListWasEmpty]
3269
3270Description:
3271Returns the first element in the list, or `ListWasEmpty` if it was empty.
3272
3273take_first : List elem, U64 -> List elem
3274
3275Description:
3276Returns the given number of elements from the beginning of the list.
3277```roc
3278List.take_first([1, 2, 3, 4, 5, 6, 7, 8], 4) == [1, 2, 3, 4]
3279```
3280If there are fewer elements in the list than the requested number,
3281returns the entire list.
3282```roc
3283List.take_first([1, 2], 5) == [1, 2]
3284```
3285To *remove* elements from the beginning of the list, use `List.take_last`.
3286
3287To remove elements from both the beginning and end of the list,
3288use `List.sublist`.
3289
3290To split the list into two lists, use `List.split_at`.
3291
3292
3293take_last : List elem, U64 -> List elem
3294
3295Description:
3296Returns the given number of elements from the end of the list.
3297```roc
3298List.take_last([1, 2, 3, 4, 5, 6, 7, 8], 4) == [5, 6, 7, 8]
3299```
3300If there are fewer elements in the list than the requested number,
3301returns the entire list.
3302```roc
3303List.take_last([1, 2], 5) == [1, 2]
3304```
3305To *remove* elements from the end of the list, use `List.take_first`.
3306
3307To remove elements from both the beginning and end of the list,
3308use `List.sublist`.
3309
3310To split the list into two lists, use `List.split_at`.
3311
3312
3313drop_first : List elem, U64 -> List elem
3314
3315Description:
3316Drops n elements from the beginning of the list.
3317
3318drop_last : List elem, U64 -> List elem
3319
3320Description:
3321Drops n elements from the end of the list.
3322
3323drop_at : List elem, U64 -> List elem
3324
3325Description:
3326Drops the element at the given index from the list.
3327
3328This has no effect if the given index is outside the bounds of the list.
3329
3330To replace the element at a given index, instead of dropping it, see [List.set].
3331
3332min : List (Num a) -> Result (Num a) [ListWasEmpty]
3333
3334max : List (Num a) -> Result (Num a) [ListWasEmpty]
3335
3336join_map : List a, (a -> List b) -> List b
3337
3338Description:
3339Like [List.map], except the transformation function wraps the return value
3340in a list. At the end, all the lists get joined together into one list.
3341
3342You may know a similar function named `concat_map` in other languages.
3343
3344find_first : List elem, (elem -> Bool) -> Result elem [NotFound]
3345
3346Description:
3347Returns the first element of the list satisfying a predicate function.
3348If no satisfying element is found, an `Err NotFound` is returned.
3349
3350find_last : List elem, (elem -> Bool) -> Result elem [NotFound]
3351
3352Description:
3353Returns the last element of the list satisfying a predicate function.
3354If no satisfying element is found, an `Err NotFound` is returned.
3355
3356find_first_index : List elem, (elem -> Bool) -> Result U64 [NotFound]
3357
3358Description:
3359Returns the index at which the first element in the list
3360satisfying a predicate function can be found.
3361If no satisfying element is found, an `Err NotFound` is returned.
3362
3363find_last_index : List elem, (elem -> Bool) -> Result U64 [NotFound]
3364
3365Description:
3366Returns the last index at which the first element in the list
3367satisfying a predicate function can be found.
3368If no satisfying element is found, an `Err NotFound` is returned.
3369
3370sublist : List elem, { start : U64, len : U64 } -> List elem
3371
3372Description:
3373Returns a subsection of the given list, beginning at the `start` index and
3374including a total of `len` elements.
3375
3376If `start` is outside the bounds of the given list, returns the empty list.
3377```roc
3378List.sublist([1, 2, 3], { start: 4, len: 0 })
3379```
3380If more elements are requested than exist in the list, returns as many as it can.
3381```roc
3382List.sublist([1, 2, 3, 4, 5], { start: 2, len: 10 })
3383```
3384> If you want a sublist which goes all the way to the end of the list, no
3385> matter how long the list is, `List.take_last` can do that more efficiently.
3386
3387Some languages have a function called **`slice`** which works similarly to this.
3388
3389intersperse : List elem, elem -> List elem
3390
3391Description:
3392Intersperses `sep` between the elements of `list`
3393```roc
3394List.intersperse([1, 2, 3], 9) == [1, 9, 2, 9, 3]
3395```
3396
3397starts_with : List elem, List elem -> Bool where elem implements Eq
3398
3399Description:
3400Returns `Bool.true` if the first list starts with the second list.
3401
3402If the second list is empty, this always returns `Bool.true`; every list
3403is considered to "start with" an empty list.
3404
3405If the first list is empty, this only returns `Bool.true` if the second list is empty.
3406
3407ends_with : List elem, List elem -> Bool where elem implements Eq
3408
3409Description:
3410Returns `Bool.true` if the first list ends with the second list.
3411
3412If the second list is empty, this always returns `Bool.true`; every list
3413is considered to "end with" an empty list.
3414
3415If the first list is empty, this only returns `Bool.true` if the second list is empty.
3416
3417split_at : List elem, U64 -> { before : List elem, others : List elem }
3418
3419Description:
3420Splits the list into two lists, around the given index.
3421
3422The returned lists are labeled `before` and `others`. The `before` list will
3423contain all the elements whose index in the original list was **less than**
3424than the given index, # and the `others` list will be all the others. (This
3425means if you give an index of 0, the `before` list will be empty and the
3426`others` list will have the same elements as the original list.)
3427
3428split_on : List a, a -> List (List a) where a implements Eq
3429
3430Description:
3431Splits the input list on the delimiter element.
3432
3433```roc
3434List.split_on([1, 2, 3], 2) == [[1], [3]]
3435```
3436
3437split_on_list : List a, List a -> List (List a) where a implements Eq
3438
3439Description:
3440Splits the input list on the delimiter list.
3441
3442```roc
3443List.split_on_list([1, 2, 3], [1, 2]) == [[], [3]]
3444```
3445
3446split_first : List elem, elem -> Result { before : List elem, after : List elem } [NotFound] where elem implements Eq
3447
3448Description:
3449Returns the elements before the first occurrence of a delimiter, as well as the
3450remaining elements after that occurrence. If the delimiter is not found, returns `Err`.
3451```roc
3452List.split_first([Foo, Z, Bar, Z, Baz], Z) == Ok({ before: [Foo], after: [Bar, Z, Baz] })
3453```
3454
3455split_last : List elem, elem -> Result { before : List elem, after : List elem } [NotFound] where elem implements Eq
3456
3457Description:
3458Returns the elements before the last occurrence of a delimiter, as well as the
3459remaining elements after that occurrence. If the delimiter is not found, returns `Err`.
3460```roc
3461List.split_last([Foo, Z, Bar, Z, Baz], Z) == Ok({ before: [Foo, Z, Bar], after: [Baz] })
3462```
3463
3464chunks_of : List a, U64 -> List (List a)
3465
3466Description:
3467Splits the list into many chunks, each of which is length of the given chunk
3468size. The last chunk will be shorter if the list does not evenly divide by the
3469chunk size. If the provided list is empty or if the chunk size is 0 then the
3470result is an empty list.
3471
3472map_try : List elem, (elem -> Result ok err) -> Result (List ok) err
3473
3474Description:
3475Like [List.map], except the transformation function returns a [Result].
3476If that function ever returns `Err`, [map_try] immediately returns that `Err`.
3477If it returns `Ok` for every element, [map_try] returns `Ok` with the transformed list.
3478
3479map_try! : List elem, (elem => Result ok err) => Result (List ok) err
3480
3481Description:
3482Like [List.map_try], but with an effectful function.
3483```
3484file_list = ["a.txt", "b.txt", "c.txt"]
3485file_contents =
3486 List.map_try!(file_list, |file| File.read_utf8!(file))
3487```
3488
3489walk_try : List elem, state, (state, elem -> Result state err) -> Result state err
3490
3491Description:
3492Same as [List.walk], except you can stop walking early by returning `Err`.
3493
3494## Performance Details
3495
3496Compared to [List.walk], this can potentially visit fewer elements (which can
3497improve performance) at the cost of making each step take longer.
3498However, the added cost to each step is extremely small, and can easily
3499be outweighed if it results in skipping even a small number of elements.
3500
3501As such, it is typically better for performance to use this over [List.walk]
3502if returning `Break` earlier than the last element is expected to be common.
3503
3504concat_utf8 : List U8, Str -> List U8
3505
3506Description:
3507Concatenates the bytes of a string encoded as utf8 to a list of bytes.
3508```roc
3509expect List.concat_utf8([1, 2, 3, 4], "🐦") == [1, 2, 3, 4, 240, 159, 144, 166]
3510```
3511
3512for_each! : List a, (a => {}) => {}
3513
3514Description:
3515Run an effectful function for each element on the list.
3516
3517```roc
3518List.for_each!(["Alice", "Bob", "Charlie"], |name|
3519 create_account!(name)
3520 log!("Account created")
3521)
3522```
3523
3524If the function might fail or you need to return early, use [for_each_try!].
3525
3526for_each_try! : List a, (a => Result {} err) => Result {} err
3527
3528Description:
3529Run an effectful function that might fail for each element on the list.
3530
3531If the function returns `Err`, the iteration stops and the error is returned.
3532
3533```roc
3534List.for_each_try!(files_to_delete, |path|
3535 File.delete!(path)?
3536
3537 Stdout.line!("${path} deleted")
3538)
3539```
3540
3541walk! : List elem, state, (state, elem => state) => state
3542
3543Description:
3544Build a value from the contents of a list, using an effectful function.
3545
3546```roc
3547now_multiples = List.walk!([1, 2, 3], [], |nums, i|
3548 now = Utc.now!({}) |> Utc.to_millis_since_epoch
3549 List.append(nums, now * i)
3550)
3551```
3552
3553This is the same as [walk], except that the step function can have effects.
3554
3555walk_try! : List elem, state, (state, elem => Result state err) => Result state err
3556
3557Description:
3558Build a value from the contents of a list, using an effectful function that might fail.
3559
3560If the function returns `Err`, the iteration stops and the error is returned.
3561
3562```
3563names =
3564 List.walk_try!(
3565 ["First", "Middle", "Last"],
3566 [],
3567 |accumulator, which|
3568 Stdout.write!("${which} name: ")?
3569 name = Stdin.line!({})?
3570 Ok(List.append(accumulator, name)),
3571 )?
3572```
3573
3574This is the same as [walk_try], except that the step function can have effects.
3575
3576### Dict
3577
3578Description:
3579A [dictionary](https://en.wikipedia.org/wiki/Associative_array) that lets you
3580associate keys with values.
3581
3582## Inserting
3583
3584The most basic way to use a dictionary is to start with an empty one and
3585then:
35861. Call [Dict.insert] passing a key and a value, to associate that key with
3587that value in the dictionary.
35882. Later, call [Dict.get] passing the same key as before, and it will return
3589the value you stored.
3590
3591Here's an example of a dictionary which uses a city's name as the key, and
3592its population as the associated value.
3593```roc
3594population_by_city =
3595 Dict.empty({})
3596 |> Dict.insert("London", 8_961_989)
3597 |> Dict.insert("Philadelphia", 1_603_797)
3598 |> Dict.insert("Shanghai", 24_870_895)
3599 |> Dict.insert("Delhi", 16_787_941)
3600 |> Dict.insert("Amsterdam", 872_680)
3601```
3602## Accessing keys or values
3603
3604We can use [Dict.keys] and [Dict.values] functions to get only the keys or
3605only the values.
3606
3607You may notice that these lists have the same order as the original insertion
3608order. This will be true if all you ever do is [Dict.insert] and [Dict.get] operations
3609on the dictionary, but [Dict.remove] operations can change this order.
3610
3611## Removing
3612
3613We can remove an element from the dictionary, like so:
3614```roc
3615population_by_city
3616 |> Dict.remove("Philadelphia")
3617 |> Dict.keys
3618 ==
3619 ["London", "Amsterdam", "Shanghai", "Delhi"]
3620```
3621Notice that the order has changed. Philadelphia was not only removed from the
3622list, but Amsterdam - the last entry we inserted - has been moved into the
3623spot where Philadelphia was previously. This is exactly what [Dict.remove]
3624does. It removes an element and moves the most recent insertion into the
3625vacated spot.
3626
3627This move is done as a performance optimization, and it lets [remove] have
3628[constant time complexity](https://en.wikipedia.org/wiki/Time_complexity#Constant_time).
3629
3630Dict is inspired by [IndexMap](https://docs.rs/indexmap/latest/indexmap/map/struct.IndexMap.html).
3631The internal implementation of a dictionary is almost identical to [ankerl::unordered_dense](https://github.com/martinus/unordered_dense).
3632It has a list of keys value pairs that is ordered based on insertion.
3633It uses a list of indices into the data as the backing of a hash map.
3634
3635empty : {} -> Dict * *
3636
3637Description:
3638Return an empty dictionary.
3639```roc
3640empty_dict = Dict.empty({})
3641```
3642
3643with_capacity : U64 -> Dict * *
3644
3645Description:
3646Return a dictionary with space allocated for a number of entries. This
3647may provide a performance optimization if you know how many entries will be
3648inserted.
3649
3650reserve : Dict k v, U64 -> Dict k v
3651
3652Description:
3653Enlarge the dictionary for at least capacity additional elements
3654
3655release_excess_capacity : Dict k v -> Dict k v
3656
3657Description:
3658Shrink the memory footprint of a dictionary such that capacity is as small as possible.
3659This function will require regenerating the metadata if the size changes.
3660There will still be some overhead due to dictionary metadata always being a power of 2.
3661
3662capacity : Dict * * -> U64
3663
3664Description:
3665Returns the max number of elements the dictionary can hold before requiring a rehash.
3666```roc
3667food_dict =
3668 Dict.empty({})
3669 |> Dict.insert("apple", "fruit")
3670
3671capacity_of_dict = Dict.capacity(food_dict)
3672```
3673
3674single : k, v -> Dict k v
3675
3676Description:
3677Returns a dictionary containing the key and value provided as input.
3678```roc
3679expect
3680 Dict.single("A", "B")
3681 |> Bool.is_eq(Dict.empty({}) |> Dict.insert("A", "B"))
3682```
3683
3684from_list : List ( k, v ) -> Dict k v
3685
3686Description:
3687Returns dictionary with the keys and values specified by the input [List].
3688```roc
3689expect
3690 Dict.single(1, "One")
3691 |> Dict.insert(2, "Two")
3692 |> Dict.insert(3, "Three")
3693 |> Dict.insert(4, "Four")
3694 |> Bool.is_eq(Dict.from_list([(1, "One"), (2, "Two"), (3, "Three"), (4, "Four")]))
3695```
3696
3697## Performance Details
3698
3699This will build up from an empty dictionary to minimize totally memory use.
3700If the list has few duplicate keys, it would be faster to allocate a dictionary
3701with the same capacity of the list and walk it calling [Dict.insert]
3702
3703len : Dict * * -> U64
3704
3705Description:
3706Returns the number of values in the dictionary.
3707```roc
3708expect
3709 Dict.empty({})
3710 |> Dict.insert("One", "A Song")
3711 |> Dict.insert("Two", "Candy Canes")
3712 |> Dict.insert("Three", "Boughs of Holly")
3713 |> Dict.len
3714 |> Bool.is_eq(3)
3715```
3716
3717is_empty : Dict * * -> Bool
3718
3719Description:
3720Check if the dictionary is empty.
3721```roc
3722Dict.is_empty(Dict.empty({}) |> Dict.insert("key", 42))
3723
3724Dict.is_empty(Dict.empty({}))
3725```
3726
3727clear : Dict k v -> Dict k v
3728
3729Description:
3730Clears all elements from a dictionary keeping around the allocation if it isn't huge.
3731```roc
3732songs =
3733 Dict.empty({})
3734 |> Dict.insert("One", "A Song")
3735 |> Dict.insert("Two", "Candy Canes")
3736 |> Dict.insert("Three", "Boughs of Holly")
3737
3738clear_songs = Dict.clear(songs)
3739
3740expect Dict.len(clear_songs) == 0
3741```
3742
3743map : Dict k a, (k, a -> b) -> Dict k b
3744
3745Description:
3746Convert each value in the dictionary to something new, by calling a conversion
3747function on each of them which receives both the key and the old value. Then return a
3748new dictionary containing the same keys and the converted values.
3749
3750join_map : Dict a b, (a, b -> Dict x y) -> Dict x y
3751
3752Description:
3753Like [Dict.map], except the transformation function wraps the return value
3754in a dictionary. At the end, all the dictionaries get joined together
3755(using [Dict.insert_all]) into one dictionary.
3756
3757You may know a similar function named `concat_map` in other languages.
3758
3759walk : Dict k v, state, (state, k, v -> state) -> state
3760
3761Description:
3762Iterate through the keys and values in the dictionary and call the provided
3763function with signature `state, k, v -> state` for each value, with an
3764initial `state` value provided for the first call.
3765```roc
3766expect
3767 Dict.empty({})
3768 |> Dict.insert("Apples", 12)
3769 |> Dict.insert("Orange", 24)
3770 |> Dict.walk(0, (\count, _, qty -> count + qty))
3771 |> Bool.is_eq(36)
3772```
3773
3774walk_until : Dict k v, state, (state, k, v -> [ Continue state, Break state ]) -> state
3775
3776Description:
3777Same as [Dict.walk], except you can stop walking early.
3778
3779## Performance Details
3780
3781Compared to [Dict.walk], this can potentially visit fewer elements (which can
3782improve performance) at the cost of making each step take longer.
3783However, the added cost to each step is extremely small, and can easily
3784be outweighed if it results in skipping even a small number of elements.
3785
3786As such, it is typically better for performance to use this over [Dict.walk]
3787if returning `Break` earlier than the last element is expected to be common.
3788```roc
3789people =
3790 Dict.empty({})
3791 |> Dict.insert("Alice", 17)
3792 |> Dict.insert("Bob", 18)
3793 |> Dict.insert("Charlie", 19)
3794
3795is_adult = \_, _, age ->
3796 if age >= 18 then
3797 Break(Bool.true)
3798 else
3799 Continue(Bool.false)
3800
3801someone_is_an_adult = Dict.walk_until(people, Bool.false, is_adult)
3802
3803expect someone_is_an_adult == Bool.true
3804```
3805
3806keep_if : Dict k v, ( ( k, v ) -> Bool) -> Dict k v
3807
3808Description:
3809Run the given function on each key-value pair of a dictionary, and return
3810a dictionary with just the pairs for which the function returned `Bool.true`.
3811```roc
3812expect Dict.empty({})
3813 |> Dict.insert("Alice", 17)
3814 |> Dict.insert("Bob", 18)
3815 |> Dict.insert("Charlie", 19)
3816 |> Dict.keep_if(\(_k, v) -> v >= 18)
3817 |> Dict.len
3818 |> Bool.is_eq(2)
3819```
3820
3821drop_if : Dict k v, ( ( k, v ) -> Bool) -> Dict k v
3822
3823Description:
3824Run the given function on each key-value pair of a dictionary, and return
3825a dictionary with just the pairs for which the function returned `Bool.false`.
3826```roc
3827expect Dict.empty({})
3828 |> Dict.insert("Alice", 17)
3829 |> Dict.insert("Bob", 18)
3830 |> Dict.insert("Charlie", 19)
3831 |> Dict.drop_if(\(_k, v) -> v >= 18)
3832 |> Dict.len
3833 |> Bool.is_eq(1)
3834```
3835
3836get : Dict k v, k -> Result v [KeyNotFound]
3837
3838Description:
3839Get the value for a given key. If there is a value for the specified key it
3840will return [Ok value], otherwise return [Err KeyNotFound].
3841```roc
3842dictionary =
3843 Dict.empty({})
3844 |> Dict.insert(1,s "Apple")
3845 |> Dict.insert(2,s "Orange")
3846
3847expect Dict.get(dictionary, 1) == Ok("Apple")
3848expect Dict.get(dictionary, 2000) == Err(KeyNotFound)
3849```
3850
3851contains : Dict k v, k -> Bool
3852
3853Description:
3854Check if the dictionary has a value for a specified key.
3855```roc
3856expect
3857 Dict.empty({})
3858 |> Dict.insert(1234, "5678")
3859 |> Dict.contains(1234)
3860 |> Bool.is_eq(Bool.true)
3861```
3862
3863insert : Dict k v, k, v -> Dict k v
3864
3865Description:
3866Insert a value into the dictionary at a specified key.
3867```roc
3868expect
3869 Dict.empty({})
3870 |> Dict.insert("Apples", 12)
3871 |> Dict.get("Apples")
3872 |> Bool.is_eq(Ok(12))
3873```
3874
3875remove : Dict k v, k -> Dict k v
3876
3877Description:
3878Remove a value from the dictionary for a specified key.
3879```roc
3880expect
3881 Dict.empty({})
3882 |> Dict.insert("Some", "Value")
3883 |> Dict.remove("Some")
3884 |> Dict.len
3885 |> Bool.is_eq(0)
3886```
3887
3888update : Dict k v, k, (Result v [Missing] -> Result v [Missing]) -> Dict k v
3889
3890Description:
3891Insert or remove a value for a specified key. This function enables a
3892performance optimization for the use case of providing a default when a value
3893is missing. This is more efficient than doing both a `Dict.get` and then a
3894`Dict.insert` call, and supports being piped.
3895```roc
3896alter_value : Result Bool [Missing] -> Result Bool [Missing]
3897alter_value = \possible_value ->
3898 when possible_value is
3899 Err Missing -> Ok(Bool.false)
3900 Ok value -> if value then Err(Missing) else Ok(Bool.true)
3901
3902expect Dict.update(Dict.empty({}), "a", alter_value) == Dict.single("a", Bool.false)
3903expect Dict.update(Dict.single("a", Bool.false), "a", alter_value) == Dict.single("a", Bool.true)
3904expect Dict.update(Dict.single("a", Bool.true), "a", alter_value) == Dict.empty({})
3905```
3906
3907to_list : Dict k v -> List ( k, v )
3908
3909Description:
3910Returns the keys and values of a dictionary as a [List].
3911This requires allocating a temporary list, prefer using [Dict.to_list] or [Dict.walk] instead.
3912```roc
3913expect
3914 Dict.single(1, "One")
3915 |> Dict.insert(2, "Two")
3916 |> Dict.insert(3, "Three")
3917 |> Dict.insert(4, "Four")
3918 |> Dict.to_list
3919 |> Bool.is_eq([(1, "One"), (2, "Two"), (3, "Three"), (4, "Four")])
3920```
3921
3922keys : Dict k v -> List k
3923
3924Description:
3925Returns the keys of a dictionary as a [List].
3926This requires allocating a temporary [List], prefer using [Dict.to_list] or [Dict.walk] instead.
3927```roc
3928expect
3929 Dict.single(1, "One")
3930 |> Dict.insert(2, "Two")
3931 |> Dict.insert(3, "Three")
3932 |> Dict.insert(4, "Four")
3933 |> Dict.keys
3934 |> Bool.is_eq([1,2,3,4])
3935```
3936
3937values : Dict k v -> List v
3938
3939Description:
3940Returns the values of a dictionary as a [List].
3941This requires allocating a temporary [List], prefer using [Dict.to_list] or [Dict.walk] instead.
3942```roc
3943expect
3944 Dict.single(1, "One")
3945 |> Dict.insert(2, "Two")
3946 |> Dict.insert(3, "Three")
3947 |> Dict.insert(4, "Four")
3948 |> Dict.values
3949 |> Bool.is_eq(["One","Two","Three","Four"])
3950```
3951
3952insert_all : Dict k v, Dict k v -> Dict k v
3953
3954Description:
3955Combine two dictionaries by keeping the [union](https://en.wikipedia.org/wiki/Union_(set_theory))
3956of all the key-value pairs. This means that all the key-value pairs in
3957both dictionaries will be combined. Note that where there are pairs
3958with the same key, the value contained in the second input will be
3959retained, and the value in the first input will be removed.
3960```roc
3961first =
3962 Dict.single(1, "Not Me")
3963 |> Dict.insert(2, "And Me")
3964
3965second =
3966 Dict.single(1, "Keep Me")
3967 |> Dict.insert(3, "Me Too")
3968 |> Dict.insert(4, "And Also Me")
3969
3970expected =
3971 Dict.single(1, "Keep Me")
3972 |> Dict.insert(2, "And Me")
3973 |> Dict.insert(3, "Me Too")
3974 |> Dict.insert(4, "And Also Me")
3975
3976expect
3977 Dict.insert_all(first, second) == expected
3978```
3979
3980keep_shared : Dict k v, Dict k v -> Dict k v where v implements Eq
3981
3982Description:
3983Combine two dictionaries by keeping the [intersection](https://en.wikipedia.org/wiki/Intersection_(set_theory))
3984of all the key-value pairs. This means that we keep only those pairs
3985that are in both dictionaries. Both the key and value must match to be kept.
3986```roc
3987first =
3988 Dict.single(1, "Keep Me")
3989 |> Dict.insert(2, "And Me")
3990 |> Dict.insert(3, "Not this one")
3991
3992second =
3993 Dict.single(1, "Keep Me")
3994 |> Dict.insert(2, "And Me")
3995 |> Dict.insert(3, "This has a different value")
3996 |> Dict.insert(4, "Or Me")
3997
3998expected =
3999 Dict.single(1, "Keep Me")
4000 |> Dict.insert(2, "And Me")
4001
4002expect Dict.keep_shared(first, second) == expected
4003```
4004
4005remove_all : Dict k v, Dict k v -> Dict k v
4006
4007Description:
4008Remove the key-value pairs in the first input that are also in the second
4009using the [set difference](https://en.wikipedia.org/wiki/Complement_(set_theory)#Relative_complement)
4010of the values. This means that we will be left with only those pairs that
4011are in the first dictionary and whose keys are not in the second.
4012```roc
4013first =
4014 Dict.single(1, "Keep Me")
4015 |> Dict.insert(2, "And Me")
4016 |> Dict.insert(3, "Remove Me")
4017
4018second =
4019 Dict.single(3, "Remove Me")
4020 |> Dict.insert(4, "I do nothing...")
4021
4022expected =
4023 Dict.single(1, "Keep Me")
4024 |> Dict.insert(2, "And Me")
4025
4026expect Dict.remove_all(first, second) == expected
4027```
4028
4029### Set
4030
4031Description:
4032Provides a [set](https://en.wikipedia.org/wiki/Set_(abstract_data_type))
4033type which stores a collection of unique values, without any ordering
4034
4035empty : {} -> Set *
4036
4037Description:
4038Creates a new empty `Set`.
4039```roc
4040empty_set = Set.empty({})
4041count_values = Set.len(empty_set)
4042
4043expect count_values == 0
4044```
4045
4046with_capacity : U64 -> Set *
4047
4048Description:
4049Return a set with space allocated for a number of entries. This
4050may provide a performance optimization if you know how many entries will be
4051inserted.
4052
4053reserve : Set k, U64 -> Set k
4054
4055Description:
4056Enlarge the set for at least capacity additional elements
4057
4058release_excess_capacity : Set k -> Set k
4059
4060Description:
4061Shrink the memory footprint of a set such that capacity is as small as possible.
4062This function will require regenerating the metadata if the size changes.
4063There will still be some overhead due to dictionary metadata always being a power of 2.
4064
4065single : k -> Set k
4066
4067Description:
4068Creates a new `Set` with a single value.
4069```roc
4070single_item_set = Set.single("Apple")
4071count_values = Set.len(single_item_set)
4072
4073expect count_values == 1
4074```
4075
4076insert : Set k, k -> Set k
4077
4078Description:
4079Insert a value into a `Set`.
4080```roc
4081few_item_set =
4082 Set.empty({})
4083 |> Set.insert("Apple")
4084 |> Set.insert("Pear")
4085 |> Set.insert("Banana")
4086
4087count_values = Set.len(few_item_set)
4088
4089expect count_values == 3
4090```
4091
4092len : Set * -> U64
4093
4094Description:
4095Counts the number of values in a given `Set`.
4096```roc
4097few_item_set =
4098 Set.empty({})
4099 |> Set.insert("Apple")
4100 |> Set.insert("Pear")
4101 |> Set.insert("Banana")
4102
4103count_values = Set.len(few_item_set)
4104
4105expect count_values == 3
4106```
4107
4108capacity : Set * -> U64
4109
4110Description:
4111Returns the max number of elements the set can hold before requiring a rehash.
4112```roc
4113food_set =
4114 Set.empty({})
4115 |> Set.insert("apple")
4116
4117capacity_of_set = Set.capacity(food_set)
4118```
4119
4120is_empty : Set * -> Bool
4121
4122Description:
4123Check if the set is empty.
4124```roc
4125Set.is_empty(Set.empty({}) |> Set.insert(42))
4126
4127Set.is_empty(Set.empty({}))
4128```
4129
4130remove : Set k, k -> Set k
4131
4132Description:
4133Removes the value from the given `Set`.
4134```roc
4135numbers =
4136 Set.empty({})
4137 |> Set.insert(10)
4138 |> Set.insert(20)
4139 |> Set.remove(10)
4140
4141has10 = Set.contains(numbers, 10)
4142has20 = Set.contains(numbers, 20)
4143
4144expect has10 == Bool.false
4145expect has20 == Bool.true
4146```
4147
4148contains : Set k, k -> Bool
4149
4150Description:
4151Test if a value is in the `Set`.
4152```roc
4153Fruit : [Apple, Pear, Banana]
4154
4155fruit : Set Fruit
4156fruit =
4157 Set.single(Apple)
4158 |> Set.insert(Pear)
4159
4160has_apple = Set.contains(fruit, Apple)
4161has_banana = Set.contains(fruit, Banana)
4162
4163expect has_apple == Bool.true
4164expect has_banana == Bool.false
4165```
4166
4167to_list : Set k -> List k
4168
4169Description:
4170Retrieve the values in a `Set` as a `List`.
4171```roc
4172numbers : Set U64
4173numbers = Set.from_list([1,2,3,4,5])
4174
4175values = [1,2,3,4,5]
4176
4177expect Set.to_list(numbers) == values
4178```
4179
4180from_list : List k -> Set k
4181
4182Description:
4183Create a `Set` from a `List` of values.
4184```roc
4185values =
4186 Set.empty({})
4187 |> Set.insert(Banana)
4188 |> Set.insert(Apple)
4189 |> Set.insert(Pear)
4190
4191expect Set.from_list([Pear, Apple, Banana]) == values
4192```
4193
4194union : Set k, Set k -> Set k
4195
4196Description:
4197Combine two `Set` collection by keeping the
4198[union](https://en.wikipedia.org/wiki/Union_(set_theory))
4199of all the values pairs. This means that all of the values in both `Set`s
4200will be combined.
4201```roc
4202set1 = Set.single(Left)
4203set2 = Set.single(Right)
4204
4205expect Set.union(set1, set2) == Set.from_list([Left, Right])
4206```
4207
4208intersection : Set k, Set k -> Set k
4209
4210Description:
4211Combine two `Set`s by keeping the [intersection](https://en.wikipedia.org/wiki/Intersection_(set_theory))
4212of all the values pairs. This means that we keep only those values that are
4213in both `Set`s.
4214```roc
4215set1 = Set.from_list([Left, Other])
4216set2 = Set.from_list([Left, Right])
4217
4218expect Set.intersection(set1, set2) == Set.single(Left)
4219```
4220
4221difference : Set k, Set k -> Set k
4222
4223Description:
4224Remove the values in the first `Set` that are also in the second `Set`
4225using the [set difference](https://en.wikipedia.org/wiki/Complement_(set_theory)#Relative_complement)
4226of the values. This means that we will be left with only those values that
4227are in the first and not in the second.
4228```roc
4229first = Set.from_list([Left, Right, Up, Down])
4230second = Set.from_list([Left, Right])
4231
4232expect Set.difference(first, second) == Set.from_list([Up, Down])
4233```
4234
4235walk : Set k, state, (state, k -> state) -> state
4236
4237Description:
4238Iterate through the values of a given `Set` and build a value.
4239```roc
4240values = Set.from_list(["March", "April", "May"])
4241
4242starts_with_letter_m = \month ->
4243 when Str.to_utf8(month) is
4244 ['M', ..] -> Bool.true
4245 _ -> Bool.false
4246
4247reduce = \state, k ->
4248 if starts_with_letter_m(k) then
4249 state + 1
4250 else
4251 state
4252
4253result = Set.walk(values, 0, reduce)
4254
4255expect result == 2
4256```
4257
4258map : Set a, (a -> b) -> Set b
4259
4260Description:
4261Convert each value in the set to something new, by calling a conversion
4262function on each of them which receives the old value. Then return a
4263new set containing the converted values.
4264
4265join_map : Set a, (a -> Set b) -> Set b
4266
4267Description:
4268Like [Set.map], except the transformation function wraps the return value
4269in a set. At the end, all the sets get joined together
4270(using [Set.union]) into one set.
4271
4272You may know a similar function named `concat_map` in other languages.
4273
4274walk_until : Set k, state, (state, k -> [ Continue state, Break state ]) -> state
4275
4276Description:
4277Iterate through the values of a given `Set` and build a value, can stop
4278iterating part way through the collection.
4279```roc
4280numbers = Set.from_list([1,2,3,4,5,6,42,7,8,9,10])
4281
4282find42 = \state, k ->
4283 if k == 42 then
4284 Break(FoundTheAnswer)
4285 else
4286 Continue(state)
4287
4288result = Set.walk_until(numbers, NotFound, find42)
4289
4290expect result == FoundTheAnswer
4291```
4292
4293keep_if : Set k, (k -> Bool) -> Set k
4294
4295Description:
4296Run the given function on each element in the `Set`, and return
4297a `Set` with just the elements for which the function returned `Bool.true`.
4298```roc
4299expect Set.from_list([1,2,3,4,5])
4300 |> Set.keep_if(\k -> k >= 3)
4301 |> Bool.is_eq(Set.from_list([3,4,5]))
4302```
4303
4304drop_if : Set k, (k -> Bool) -> Set k
4305
4306Description:
4307Run the given function on each element in the `Set`, and return
4308a `Set` with just the elements for which the function returned `Bool.false`.
4309```roc
4310expect Set.from_list [1,2,3,4,5]
4311 |> Set.drop_if(\k -> k >= 3)
4312 |> Bool.is_eq(Set.from_list([1,2]))
4313```
4314
4315### Decode
4316
4317DecodeError : [TooShort]
4318
4319Description:
4320Error types when decoding a `List U8` of utf-8 bytes using a [Decoder]
4321
4322Description:
4323Return type of a [Decoder].
4324
4325This can be useful when creating a [custom](#custom) decoder or when
4326using [from_bytes_partial](#from_bytes_partial). For example writing unit tests,
4327such as;
4328```roc
4329expect
4330 input = "\"hello\", " |> Str.to_utf8
4331 actual = Decode.from_bytes_partial(input, Json.json)
4332 expected = Ok("hello")
4333
4334 actual.result == expected
4335```
4336
4337Description:
4338Decodes a `List U8` of utf-8 bytes where `val` is the type of the decoded
4339value, and `fmt` is a [Decoder] which implements the [DecoderFormatting]
4340ability
4341
4342Decoding : implements
4343 decoder : Decoder val fmt
4344 where val implements Decoding, fmt implements DecoderFormatting
4345
4346Description:
4347Definition of the [Decoding] ability
4348
4349DecoderFormatting : implements
4350 u8 : Decoder U8 fmt
4351 where fmt implements DecoderFormatting
4352 u16 : Decoder U16 fmt
4353 where fmt implements DecoderFormatting
4354 u32 : Decoder U32 fmt
4355 where fmt implements DecoderFormatting
4356 u64 : Decoder U64 fmt
4357 where fmt implements DecoderFormatting
4358 u128 : Decoder U128 fmt
4359 where fmt implements DecoderFormatting
4360 i8 : Decoder I8 fmt
4361 where fmt implements DecoderFormatting
4362 i16 : Decoder I16 fmt
4363 where fmt implements DecoderFormatting
4364 i32 : Decoder I32 fmt
4365 where fmt implements DecoderFormatting
4366 i64 : Decoder I64 fmt
4367 where fmt implements DecoderFormatting
4368 i128 : Decoder I128 fmt
4369 where fmt implements DecoderFormatting
4370 f32 : Decoder F32 fmt
4371 where fmt implements DecoderFormatting
4372 f64 : Decoder F64 fmt
4373 where fmt implements DecoderFormatting
4374 dec : Decoder Dec fmt
4375 where fmt implements DecoderFormatting
4376 bool : Decoder Bool fmt
4377 where fmt implements DecoderFormatting
4378 string : Decoder Str fmt
4379 where fmt implements DecoderFormatting
4380 list : Decoder elem fmt -> Decoder (List elem) fmt
4381 where fmt implements DecoderFormatting
4382 record :
4383 state,
4384 (state,
4385 Str
4386 ->
4387 [
4388 Keep (Decoder state fmt),
4389 Skip
4390 ]),
4391 (state, fmt -> Result val DecodeError)
4392 -> Decoder val fmt
4393 where fmt implements DecoderFormatting
4394 tuple :
4395 state,
4396 (state,
4397 U64
4398 ->
4399 [
4400 Next (Decoder state fmt),
4401 TooLong
4402 ]),
4403 (state -> Result val DecodeError)
4404 -> Decoder val fmt
4405 where fmt implements DecoderFormatting
4406
4407Description:
4408Definition of the [DecoderFormatting] ability
4409
4410custom : (List U8, fmt -> DecodeResult val) -> Decoder val fmt where fmt implements DecoderFormatting
4411
4412Description:
4413Build a custom [Decoder] function. For example the implementation of
4414`decode_bool` could be defined as follows;
4415
4416```roc
4417decode_bool = Decode.custom \bytes, @Json({}) ->
4418 when bytes is
4419 ['f', 'a', 'l', 's', 'e', ..] -> { result: Ok(Bool.false), rest: List.drop_first(bytes, 5) }
4420 ['t', 'r', 'u', 'e', ..] -> { result: Ok Bool.true, rest: List.drop_first(bytes, 4) }
4421 _ -> { result: Err(TooShort), rest: bytes }
4422```
4423
4424decode_with : List U8, Decoder val fmt, fmt -> DecodeResult val where fmt implements DecoderFormatting
4425
4426Description:
4427Decode a `List U8` utf-8 bytes using a specific [Decoder] function
4428
4429from_bytes_partial : List U8, fmt -> DecodeResult val where val implements Decoding, fmt implements DecoderFormatting
4430
4431Description:
4432Decode a `List U8` utf-8 bytes and return a [DecodeResult](#DecodeResult)
4433```roc
4434expect
4435 input = "\"hello\", " |> Str.to_utf8
4436 actual = Decode.from_bytes_partial(input Json.json)
4437 expected = Ok("hello")
4438
4439 actual.result == expected
4440```
4441
4442from_bytes : List U8, fmt -> Result val [Leftover (List U8)]DecodeError where val implements Decoding, fmt implements DecoderFormatting
4443
4444Description:
4445Decode a `List U8` utf-8 bytes and return a [Result] with no leftover bytes
4446expected. If successful returns `Ok val`, however, if there are bytes
4447remaining returns `Err Leftover (List U8)`.
4448```roc
4449expect
4450 input = "\"hello\", " |> Str.to_utf8
4451 actual = Decode.from_bytes(input, Json.json)
4452 expected = Ok("hello")
4453
4454 actual == expected
4455```
4456
4457map_result : DecodeResult a, (a -> b) -> DecodeResult b
4458
4459Description:
4460Transform the `val` of a [DecodeResult]
4461
4462### Encode
4463
4464Encoding : implements
4465 to_encoder : val -> Encoder fmt
4466 where val implements Encoding, fmt implements EncoderFormatting
4467
4468EncoderFormatting : implements
4469 u8 : U8 -> Encoder fmt
4470 where fmt implements EncoderFormatting
4471 u16 : U16 -> Encoder fmt
4472 where fmt implements EncoderFormatting
4473 u32 : U32 -> Encoder fmt
4474 where fmt implements EncoderFormatting
4475 u64 : U64 -> Encoder fmt
4476 where fmt implements EncoderFormatting
4477 u128 : U128 -> Encoder fmt
4478 where fmt implements EncoderFormatting
4479 i8 : I8 -> Encoder fmt
4480 where fmt implements EncoderFormatting
4481 i16 : I16 -> Encoder fmt
4482 where fmt implements EncoderFormatting
4483 i32 : I32 -> Encoder fmt
4484 where fmt implements EncoderFormatting
4485 i64 : I64 -> Encoder fmt
4486 where fmt implements EncoderFormatting
4487 i128 : I128 -> Encoder fmt
4488 where fmt implements EncoderFormatting
4489 f32 : F32 -> Encoder fmt
4490 where fmt implements EncoderFormatting
4491 f64 : F64 -> Encoder fmt
4492 where fmt implements EncoderFormatting
4493 dec : Dec -> Encoder fmt
4494 where fmt implements EncoderFormatting
4495 bool : Bool -> Encoder fmt
4496 where fmt implements EncoderFormatting
4497 string : Str -> Encoder fmt
4498 where fmt implements EncoderFormatting
4499 list : List elem, (elem -> Encoder fmt) -> Encoder fmt
4500 where fmt implements EncoderFormatting
4501 record : List
4502 {
4503 key : Str,
4504 value : Encoder fmt
4505 }
4506 -> Encoder fmt
4507 where fmt implements EncoderFormatting
4508 tuple : List (Encoder fmt) -> Encoder fmt
4509 where fmt implements EncoderFormatting
4510 tag : Str, List (Encoder fmt) -> Encoder fmt
4511 where fmt implements EncoderFormatting
4512
4513custom : (List U8, fmt -> List U8) -> Encoder fmt where fmt implements EncoderFormatting
4514
4515Description:
4516Creates a custom encoder from a given function.
4517
4518```roc
4519expect
4520 # Appends the byte 42
4521 custom_encoder = Encode.custom(\bytes, _fmt -> List.append(bytes, 42))
4522
4523 actual = Encode.append_with([], custom_encoder, Core.json)
4524 expected = [42] # Expected result is a list with a single byte, 42
4525
4526 actual == expected
4527```
4528
4529append_with : List U8, Encoder fmt, fmt -> List U8 where fmt implements EncoderFormatting
4530
4531append : List U8, val, fmt -> List U8 where val implements Encoding, fmt implements EncoderFormatting
4532
4533Description:
4534Appends the encoded representation of a value to an existing list of bytes.
4535
4536```roc
4537expect
4538 actual = Encode.append([], { foo: 43 }, Core.json)
4539 expected = Str.to_utf8("""{"foo":43}""")
4540
4541 actual == expected
4542```
4543
4544to_bytes : val, fmt -> List U8 where val implements Encoding, fmt implements EncoderFormatting
4545
4546Description:
4547Encodes a value to a list of bytes (`List U8`) according to the specified format.
4548
4549```roc
4550expect
4551 foo_rec = { foo: 42 }
4552
4553 actual = Encode.to_bytes(foo_rec, Core.json)
4554 expected = Str.to_utf8("""{"foo":42}""")
4555
4556 actual == expected
4557```
4558
4559### Hash
4560
4561Hash : implements
4562 hash : hasher, a -> hasher
4563 where a implements Hash, hasher implements Hasher
4564
4565Description:
4566A value that can be hashed.
4567
4568Hasher : implements
4569 add_bytes : a, List U8 -> a
4570 where a implements Hasher
4571 add_u8 : a, U8 -> a
4572 where a implements Hasher
4573 add_u16 : a, U16 -> a
4574 where a implements Hasher
4575 add_u32 : a, U32 -> a
4576 where a implements Hasher
4577 add_u64 : a, U64 -> a
4578 where a implements Hasher
4579 add_u128 : a, U128 -> a
4580 where a implements Hasher
4581 complete : a -> U64
4582 where a implements Hasher
4583
4584Description:
4585Describes a hashing algorithm that is fed bytes and produces an integer hash.
4586
4587The [Hasher] ability describes general-purpose hashers. It only allows
4588emission of 64-bit unsigned integer hashes. It is not suitable for
4589cryptographically-secure hashing.
4590
4591Description:
4592Adds a string into a [Hasher] by hashing its UTF-8 bytes.
4593
4594Description:
4595Adds a list of [Hash]able elements to a [Hasher] by hashing each element.
4596
4597hash_bool : a, Bool -> a where a implements Hasher
4598
4599Description:
4600Adds a single [Bool] to a hasher.
4601
4602hash_i8 : a, I8 -> a where a implements Hasher
4603
4604Description:
4605Adds a single I8 to a hasher.
4606
4607hash_i16 : a, I16 -> a where a implements Hasher
4608
4609Description:
4610Adds a single I16 to a hasher.
4611
4612hash_i32 : a, I32 -> a where a implements Hasher
4613
4614Description:
4615Adds a single I32 to a hasher.
4616
4617hash_i64 : a, I64 -> a where a implements Hasher
4618
4619Description:
4620Adds a single I64 to a hasher.
4621
4622hash_i128 : a, I128 -> a where a implements Hasher
4623
4624Description:
4625Adds a single I128 to a hasher.
4626
4627hash_dec : a, Dec -> a where a implements Hasher
4628
4629Description:
4630Adds a single [Dec] to a hasher.
4631
4632Description:
4633Adds a container of [Hash]able elements to a [Hasher] by hashing each element.
4634The container is iterated using the walk method passed in.
4635The order of the elements does not affect the final hash.
4636
4637### Box
4638
4639box : a -> Box a
4640
4641Description:
4642Allocates a value on the heap. Boxing is an expensive process as it copies
4643the value from the stack to the heap. This may provide a performance
4644optimization for advanced use cases with large values. A platform may require
4645that some values are boxed.
4646```roc
4647expect Box.unbox(Box.box("Stack Faster")) == "Stack Faster"
4648```
4649
4650unbox : Box a -> a
4651
4652Description:
4653Returns a boxed value.
4654```roc
4655expect Box.unbox(Box.box("Stack Faster") == "Stack Faster"
4656```
4657
4658### Inspect
4659
4660KeyValWalker : collection, state, (state, key, val -> state) -> state
4661
4662ElemWalker : collection, state, (state, elem -> state) -> state
4663
4664InspectFormatter : implements
4665 init : {} -> f
4666 where f implements InspectFormatter
4667 tag : Str, List (Inspector f) -> Inspector f
4668 where f implements InspectFormatter
4669 tuple : List (Inspector f) -> Inspector f
4670 where f implements InspectFormatter
4671 record : List
4672 {
4673 key : Str,
4674 value : Inspector f
4675 }
4676 -> Inspector f
4677 where f implements InspectFormatter
4678 bool : Bool -> Inspector f
4679 where f implements InspectFormatter
4680 str : Str -> Inspector f
4681 where f implements InspectFormatter
4682 list :
4683 list,
4684 ElemWalker state list elem,
4685 (elem -> Inspector f)
4686 -> Inspector f
4687 where f implements InspectFormatter
4688 set :
4689 set,
4690 ElemWalker state set elem,
4691 (elem -> Inspector f)
4692 -> Inspector f
4693 where f implements InspectFormatter
4694 dict :
4695 dict,
4696 KeyValWalker state dict key value,
4697 (key -> Inspector f),
4698 (value -> Inspector f)
4699 -> Inspector f
4700 where f implements InspectFormatter
4701 opaque : * -> Inspector f
4702 where f implements InspectFormatter
4703 function : * -> Inspector f
4704 where f implements InspectFormatter
4705 u8 : U8 -> Inspector f
4706 where f implements InspectFormatter
4707 i8 : I8 -> Inspector f
4708 where f implements InspectFormatter
4709 u16 : U16 -> Inspector f
4710 where f implements InspectFormatter
4711 i16 : I16 -> Inspector f
4712 where f implements InspectFormatter
4713 u32 : U32 -> Inspector f
4714 where f implements InspectFormatter
4715 i32 : I32 -> Inspector f
4716 where f implements InspectFormatter
4717 u64 : U64 -> Inspector f
4718 where f implements InspectFormatter
4719 i64 : I64 -> Inspector f
4720 where f implements InspectFormatter
4721 u128 : U128 -> Inspector f
4722 where f implements InspectFormatter
4723 i128 : I128 -> Inspector f
4724 where f implements InspectFormatter
4725 f32 : F32 -> Inspector f
4726 where f implements InspectFormatter
4727 f64 : F64 -> Inspector f
4728 where f implements InspectFormatter
4729 dec : Dec -> Inspector f
4730 where f implements InspectFormatter
4731
4732custom : (f -> f) -> Inspector f where f implements InspectFormatter
4733
4734apply : Inspector f, f -> f where f implements InspectFormatter
4735
4736Inspect : implements
4737 to_inspector : val -> Inspector f
4738 where val implements Inspect, f implements InspectFormatter
4739
4740inspect : val -> f where val implements Inspect, f implements InspectFormatter
4741
4742to_str : val -> Str where val implements Inspect
4743