@grain/stdlib 0.4.3 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/array.gr +118 -49
- package/array.md +60 -5
- package/buffer.gr +95 -41
- package/hash.gr +7 -2
- package/list.gr +54 -0
- package/number.gr +24 -6
- package/number.md +32 -0
- package/option.gr +244 -37
- package/option.md +579 -0
- package/package.json +1 -1
- package/queue.gr +98 -29
- package/queue.md +191 -0
- package/range.md +1 -1
- package/regex.md +9 -9
- package/result.gr +216 -70
- package/result.md +446 -0
- package/runtime/stringUtils.gr +172 -0
- package/set.gr +172 -5
- package/set.md +502 -0
- package/string.gr +30 -3
- package/string.md +31 -0
package/hash.gr
CHANGED
|
@@ -227,7 +227,7 @@ let rec hashOne = (val, depth) => {
|
|
|
227
227
|
*
|
|
228
228
|
* @since v0.1.0
|
|
229
229
|
*/
|
|
230
|
-
export let hash = (anything) => {
|
|
230
|
+
export let rec hash = (anything) => {
|
|
231
231
|
h = seed
|
|
232
232
|
|
|
233
233
|
hashOne(WasmI32.fromGrain(anything), 0n)
|
|
@@ -235,5 +235,10 @@ export let hash = (anything) => {
|
|
|
235
235
|
|
|
236
236
|
// Tag the number on the way out.
|
|
237
237
|
// Since Grain has proper modulus, negative numbers are okay.
|
|
238
|
-
tagSimpleNumber(h)
|
|
238
|
+
let result = tagSimpleNumber(h)
|
|
239
|
+
|
|
240
|
+
Memory.decRef(WasmI32.fromGrain(hash))
|
|
241
|
+
Memory.decRef(WasmI32.fromGrain(anything))
|
|
242
|
+
|
|
243
|
+
result
|
|
239
244
|
}
|
package/list.gr
CHANGED
|
@@ -329,3 +329,57 @@ let join = (separator: String, items: List<String>) => {
|
|
|
329
329
|
Some(s) => s,
|
|
330
330
|
}
|
|
331
331
|
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Reverses the first list and appends the second list to the end.
|
|
335
|
+
*
|
|
336
|
+
* @param list1: The list to reverse
|
|
337
|
+
* @param list2: The list to append
|
|
338
|
+
* @since v0.4.5
|
|
339
|
+
*/
|
|
340
|
+
let rec revAppend = (list1, list2) => {
|
|
341
|
+
match (list1) {
|
|
342
|
+
[hd, ...tl] => revAppend(tl, [hd, ...list2]),
|
|
343
|
+
[] => list2
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Sorts the given list based on a given comparator function. The resulting list is sorted in increasing order.
|
|
349
|
+
*
|
|
350
|
+
* Ordering is calculated using a comparator function which takes two list elements and must return 0 if both are equal, a positive number if the first is greater, and a negative number if the first is smaller.
|
|
351
|
+
* @param comp: The comparator function used to indicate sort order
|
|
352
|
+
* @param list: The list to be sorted
|
|
353
|
+
* @since v0.4.5
|
|
354
|
+
*/
|
|
355
|
+
let sort = (comp, list) => {
|
|
356
|
+
let rec merge = (left, right, list) => {
|
|
357
|
+
match((left, right)){
|
|
358
|
+
(_, []) => {
|
|
359
|
+
revAppend(list, left)
|
|
360
|
+
},
|
|
361
|
+
([], _) => {
|
|
362
|
+
revAppend(list, right)
|
|
363
|
+
},
|
|
364
|
+
([lhd, ...ltl], [rhd, ...rtl]) => {
|
|
365
|
+
if(comp(lhd, rhd) < 0){
|
|
366
|
+
merge(ltl, right, append([lhd],list))
|
|
367
|
+
}else{
|
|
368
|
+
merge(left, rtl, append([rhd], list))
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
let rec mergesort = (list) => {
|
|
375
|
+
if(length(list) <= 1){
|
|
376
|
+
list
|
|
377
|
+
}else{
|
|
378
|
+
let middle = length(list) / 2
|
|
379
|
+
let (left, right) = part(middle, list)
|
|
380
|
+
merge(mergesort(left), mergesort(right), [])
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
mergesort(list)
|
|
385
|
+
}
|
package/number.gr
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
isFloat,
|
|
16
16
|
isBoxedNumber
|
|
17
17
|
} from "runtime/numbers"
|
|
18
|
+
import { parseInt } from "runtime/stringUtils"
|
|
18
19
|
import { newFloat64, newInt64 } from "runtime/dataStructures"
|
|
19
20
|
import Tags from "runtime/unsafe/tags"
|
|
20
21
|
|
|
@@ -76,9 +77,9 @@ export let rec sqrt = (x: Number) => {
|
|
|
76
77
|
let x = WasmI32.fromGrain(x)
|
|
77
78
|
let sqrtd = WasmF64.sqrt(xval)
|
|
78
79
|
let ret = if (!isFloat(x) && WasmF64.eq(sqrtd, WasmF64.trunc(sqrtd))) {
|
|
79
|
-
WasmI32.toGrain(reducedInteger(WasmI64.truncF64S(sqrtd))): Number
|
|
80
|
+
WasmI32.toGrain(reducedInteger(WasmI64.truncF64S(sqrtd))): (Number)
|
|
80
81
|
} else {
|
|
81
|
-
WasmI32.toGrain(newFloat64(sqrtd)): Number
|
|
82
|
+
WasmI32.toGrain(newFloat64(sqrtd)): (Number)
|
|
82
83
|
}
|
|
83
84
|
Memory.decRef(WasmI32.fromGrain(x))
|
|
84
85
|
Memory.decRef(WasmI32.fromGrain(sqrt))
|
|
@@ -119,7 +120,7 @@ export let max = (x: Number, y: Number) => if (x > y) x else y
|
|
|
119
120
|
export let rec ceil = (x: Number) => {
|
|
120
121
|
let xval = coerceNumberToWasmF64(x)
|
|
121
122
|
let ceiling = WasmI64.truncF64S(WasmF64.ceil(xval))
|
|
122
|
-
let ret = WasmI32.toGrain(reducedInteger(ceiling)): Number
|
|
123
|
+
let ret = WasmI32.toGrain(reducedInteger(ceiling)): (Number)
|
|
123
124
|
Memory.decRef(WasmI32.fromGrain(x))
|
|
124
125
|
Memory.decRef(WasmI32.fromGrain(ceil))
|
|
125
126
|
ret
|
|
@@ -137,7 +138,7 @@ export let rec ceil = (x: Number) => {
|
|
|
137
138
|
export let rec floor = (x: Number) => {
|
|
138
139
|
let xval = coerceNumberToWasmF64(x)
|
|
139
140
|
let floored = WasmI64.truncF64S(WasmF64.floor(xval))
|
|
140
|
-
let ret = WasmI32.toGrain(reducedInteger(floored)): Number
|
|
141
|
+
let ret = WasmI32.toGrain(reducedInteger(floored)): (Number)
|
|
141
142
|
Memory.decRef(WasmI32.fromGrain(x))
|
|
142
143
|
Memory.decRef(WasmI32.fromGrain(floor))
|
|
143
144
|
ret
|
|
@@ -155,7 +156,7 @@ export let rec floor = (x: Number) => {
|
|
|
155
156
|
export let rec trunc = (x: Number) => {
|
|
156
157
|
let xval = coerceNumberToWasmF64(x)
|
|
157
158
|
let trunced = WasmI64.truncF64S(xval)
|
|
158
|
-
let ret = WasmI32.toGrain(reducedInteger(trunced)): Number
|
|
159
|
+
let ret = WasmI32.toGrain(reducedInteger(trunced)): (Number)
|
|
159
160
|
Memory.decRef(WasmI32.fromGrain(x))
|
|
160
161
|
Memory.decRef(WasmI32.fromGrain(trunc))
|
|
161
162
|
ret
|
|
@@ -173,7 +174,7 @@ export let rec trunc = (x: Number) => {
|
|
|
173
174
|
export let rec round = (x: Number) => {
|
|
174
175
|
let xval = coerceNumberToWasmF64(x)
|
|
175
176
|
let rounded = WasmI64.truncF64S(WasmF64.nearest(xval))
|
|
176
|
-
let ret = WasmI32.toGrain(reducedInteger(rounded)): Number
|
|
177
|
+
let ret = WasmI32.toGrain(reducedInteger(rounded)): (Number)
|
|
177
178
|
Memory.decRef(WasmI32.fromGrain(x))
|
|
178
179
|
Memory.decRef(WasmI32.fromGrain(round))
|
|
179
180
|
ret
|
|
@@ -305,3 +306,20 @@ export let rec isInfinite = (x: Number) => {
|
|
|
305
306
|
Memory.decRef(WasmI32.fromGrain(isInfinite))
|
|
306
307
|
ret
|
|
307
308
|
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Parses a string representation of an integer into a `Number` using the
|
|
312
|
+
* specified radix (also known as a number system "base").
|
|
313
|
+
*
|
|
314
|
+
* If the string has a radix prefix (i.e. "0x"/"0X", "0o"/"0O", or "0b"/"0B"
|
|
315
|
+
* for radixes 16, 8, or 2 respectively), the supplied radix is ignored in
|
|
316
|
+
* favor of the prefix. Underscores that appear in the numeric portion of the
|
|
317
|
+
* input are ignored.
|
|
318
|
+
*
|
|
319
|
+
* @param input: The string to parse
|
|
320
|
+
* @param radix: The number system base to use when parsing the input string
|
|
321
|
+
* @returns `Ok(value)` containing the parsed number on a successful parse or `Err(msg)` containing an error message string otherwise
|
|
322
|
+
*
|
|
323
|
+
* @since v0.4.5
|
|
324
|
+
*/
|
|
325
|
+
export parseInt
|
package/number.md
CHANGED
|
@@ -422,3 +422,35 @@ Returns:
|
|
|
422
422
|
|----|-----------|
|
|
423
423
|
|`Bool`|`true` if the value is infinite, otherwise `false`|
|
|
424
424
|
|
|
425
|
+
### Number.**parseInt**
|
|
426
|
+
|
|
427
|
+
<details disabled>
|
|
428
|
+
<summary tabindex="-1">Added in <code>next</code></summary>
|
|
429
|
+
No other changes yet.
|
|
430
|
+
</details>
|
|
431
|
+
|
|
432
|
+
```grain
|
|
433
|
+
parseInt : (String, Number) -> Result<Number, String>
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
Parses a string representation of an integer into a `Number` using the
|
|
437
|
+
specified radix (also known as a number system "base").
|
|
438
|
+
|
|
439
|
+
If the string has a radix prefix (i.e. "0x"/"0X", "0o"/"0O", or "0b"/"0B"
|
|
440
|
+
for radixes 16, 8, or 2 respectively), the supplied radix is ignored in
|
|
441
|
+
favor of the prefix. Underscores that appear in the numeric portion of the
|
|
442
|
+
input are ignored.
|
|
443
|
+
|
|
444
|
+
Parameters:
|
|
445
|
+
|
|
446
|
+
|param|type|description|
|
|
447
|
+
|-----|----|-----------|
|
|
448
|
+
|`input`|`String`|The string to parse|
|
|
449
|
+
|`radix`|`Number`|The number system base to use when parsing the input string|
|
|
450
|
+
|
|
451
|
+
Returns:
|
|
452
|
+
|
|
453
|
+
|type|description|
|
|
454
|
+
|----|-----------|
|
|
455
|
+
|`Result<Number, String>`|`Ok(value)` containing the parsed number on a successful parse or `Err(msg)` containing an error message string otherwise|
|
|
456
|
+
|
package/option.gr
CHANGED
|
@@ -1,78 +1,195 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @module Option: Utilities for working with the Option data type.
|
|
3
|
+
*
|
|
4
|
+
* The Option type is an enum that represents the possibility of something being present (with the `Some` variant), or not (with the `None` variant). There’s no standalone `null` or `nil` type in Grain; use an Option where you would normally reach for `null` or `nil`.
|
|
5
|
+
*
|
|
6
|
+
* @example import Option from "option"
|
|
7
|
+
*
|
|
8
|
+
* @example let hasValue = Some(1234) // Creates an Option containing 1234
|
|
9
|
+
* @example let noValue = None // Creates an Option containing nothing
|
|
10
|
+
*
|
|
11
|
+
* @since v0.2.0
|
|
12
|
+
*/
|
|
2
13
|
|
|
3
|
-
|
|
14
|
+
/**
|
|
15
|
+
* @section Values: Functions for working with the Option data type.
|
|
16
|
+
*/
|
|
4
17
|
|
|
5
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Checks if the Option is the `Some` variant.
|
|
20
|
+
*
|
|
21
|
+
* @param option: The option to check
|
|
22
|
+
* @returns `true` if the Option is the `Some` variant or `false` otherwise
|
|
23
|
+
*
|
|
24
|
+
* @since v0.2.0
|
|
25
|
+
*/
|
|
26
|
+
export let isSome = (option) => {
|
|
6
27
|
match (option) {
|
|
7
28
|
Some(_) => true,
|
|
8
29
|
None => false
|
|
9
30
|
}
|
|
10
31
|
}
|
|
11
32
|
|
|
12
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Checks if the Option is the `None` variant.
|
|
35
|
+
*
|
|
36
|
+
* @param option: The option to check
|
|
37
|
+
* @returns `true` if the Option is the `None` variant or `false` otherwise
|
|
38
|
+
*
|
|
39
|
+
* @since v0.2.0
|
|
40
|
+
*/
|
|
41
|
+
export let isNone = (option) => {
|
|
13
42
|
match (option) {
|
|
14
43
|
None => true,
|
|
15
44
|
Some(_) => false
|
|
16
45
|
}
|
|
17
46
|
}
|
|
18
47
|
|
|
19
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Checks if the Option is the `Some` variant and contains the given value. Uses the generic `==` equality operator.
|
|
50
|
+
*
|
|
51
|
+
* @param value: The value to search for
|
|
52
|
+
* @param option: The option to search
|
|
53
|
+
* @returns `true` if the Option is equivalent to `Some(value)` or `false` otherwise
|
|
54
|
+
*
|
|
55
|
+
* @since v0.2.0
|
|
56
|
+
*/
|
|
57
|
+
export let contains = (value, option) => {
|
|
20
58
|
match (option) {
|
|
21
|
-
Some(x) => x ==
|
|
59
|
+
Some(x) => x == value,
|
|
22
60
|
None => false
|
|
23
61
|
}
|
|
24
62
|
}
|
|
25
63
|
|
|
26
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Extracts the value inside a `Some` option, otherwise throws an
|
|
66
|
+
* exception containing the message provided.
|
|
67
|
+
*
|
|
68
|
+
* @param msg: The message to use upon failure
|
|
69
|
+
* @param option: The option to extract a value from
|
|
70
|
+
* @returns The unwrapped value if the Option is the `Some` variant
|
|
71
|
+
*
|
|
72
|
+
* @since v0.2.0
|
|
73
|
+
*/
|
|
74
|
+
export let expect = (msg, option) => {
|
|
27
75
|
match (option) {
|
|
28
76
|
Some(x) => x,
|
|
29
77
|
None => fail msg
|
|
30
78
|
}
|
|
31
79
|
}
|
|
32
80
|
|
|
33
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Extracts the value inside a `Some` option, otherwise
|
|
83
|
+
* throws an exception containing a default message.
|
|
84
|
+
*
|
|
85
|
+
* @param option: The option to extract the value from
|
|
86
|
+
* @returns The unwrapped value if the Option is the `Some` variant
|
|
87
|
+
*
|
|
88
|
+
* @since v0.2.0
|
|
89
|
+
*/
|
|
90
|
+
export let unwrap = (option) => {
|
|
34
91
|
expect("Could not unwrap None value", option)
|
|
35
92
|
}
|
|
36
93
|
|
|
37
|
-
|
|
94
|
+
/**
|
|
95
|
+
* Extracts the value inside a `Some` option or provide the default value if `None`.
|
|
96
|
+
*
|
|
97
|
+
* @param default: The default value
|
|
98
|
+
* @param option: The option to unwrap
|
|
99
|
+
* @returns The unwrapped value if the Option is the `Some` variant or the default value otherwise
|
|
100
|
+
*
|
|
101
|
+
* @since v0.2.0
|
|
102
|
+
*/
|
|
103
|
+
export let unwrapWithDefault = (default, option) => {
|
|
38
104
|
match (option) {
|
|
39
105
|
Some(x) => x,
|
|
40
106
|
None => default
|
|
41
107
|
}
|
|
42
108
|
}
|
|
43
109
|
|
|
44
|
-
|
|
110
|
+
/**
|
|
111
|
+
* If the Option is `Some(value)`, applies the given function to the `value` and wraps the new value in a `Some` variant.
|
|
112
|
+
*
|
|
113
|
+
* @param fn: The function to call on the value of a `Some` variant
|
|
114
|
+
* @param option: The option to map
|
|
115
|
+
* @returns A new `Some` variant produced by the mapping function if the variant was `Some` or the unmodified `None` otherwise
|
|
116
|
+
*
|
|
117
|
+
* @since v0.2.0
|
|
118
|
+
*/
|
|
119
|
+
export let map = (fn, option) => {
|
|
45
120
|
match (option) {
|
|
46
121
|
Some(x) => Some(fn(x)),
|
|
47
122
|
None => None
|
|
48
123
|
}
|
|
49
124
|
}
|
|
50
125
|
|
|
51
|
-
|
|
126
|
+
/**
|
|
127
|
+
* If the Option is `Some(value)`, applies the given function to the `value` to produce a new value, otherwise uses the default value.
|
|
128
|
+
* Useful for unwrapping an Option while providing a fallback for any `None` variants.
|
|
129
|
+
*
|
|
130
|
+
* @param fn: The function to call on the value of a `Some` variant
|
|
131
|
+
* @param default: A fallback value for a `None` variant
|
|
132
|
+
* @param option: The option to map
|
|
133
|
+
* @returns The value produced by the mapping function if the Option is of the `Some` variant or the default value otherwise
|
|
134
|
+
*
|
|
135
|
+
* @since v0.2.0
|
|
136
|
+
*/
|
|
137
|
+
export let mapWithDefault = (fn, default, option) => {
|
|
52
138
|
match (option) {
|
|
53
139
|
Some(x) => fn(x),
|
|
54
140
|
None => default
|
|
55
141
|
}
|
|
56
142
|
}
|
|
57
143
|
|
|
58
|
-
|
|
144
|
+
/**
|
|
145
|
+
* If the Option is `Some(value)`, applies the `fn` function to the `value` to produce a new value.
|
|
146
|
+
* If the Option is `None`, calls the `defaultFn` function to produce a new value.
|
|
147
|
+
* Useful for unwrapping an Option into a value, whether it is `Some` or `None`.
|
|
148
|
+
*
|
|
149
|
+
* @param fn: The function to call on the value of a `Some` variant
|
|
150
|
+
* @param defaultFn: The default function
|
|
151
|
+
* @param option: The option to map
|
|
152
|
+
* @returns The value produced by one of the mapping functions
|
|
153
|
+
*
|
|
154
|
+
* @since v0.2.0
|
|
155
|
+
*/
|
|
156
|
+
export let mapWithDefaultFn = (fn, defaultFn, option) => {
|
|
59
157
|
match (option) {
|
|
60
158
|
Some(x) => fn(x),
|
|
61
159
|
None => defaultFn()
|
|
62
160
|
}
|
|
63
161
|
}
|
|
64
162
|
|
|
65
|
-
|
|
163
|
+
/**
|
|
164
|
+
* If the Option is `Some(value)`, applies the given function to the `value` to produce a new Option.
|
|
165
|
+
*
|
|
166
|
+
* @param fn: The function to call on the value of a `Some` variant
|
|
167
|
+
* @param option: The option to map
|
|
168
|
+
* @returns A new Option produced by the mapping function if the variant was `Some` or the unmodified `None` otherwise
|
|
169
|
+
*
|
|
170
|
+
* @since v0.2.0
|
|
171
|
+
*/
|
|
172
|
+
export let flatMap = (fn, option) => {
|
|
66
173
|
match (option) {
|
|
67
174
|
Some(x) => fn(x),
|
|
68
175
|
None => None
|
|
69
176
|
}
|
|
70
177
|
}
|
|
71
178
|
|
|
72
|
-
|
|
179
|
+
/**
|
|
180
|
+
* Converts `Some(value)` variants to `None` variants where the predicate function returns `false`.
|
|
181
|
+
* if the `fn` return `true` returns `Some(value)`, otherwise returns `None`.
|
|
182
|
+
*
|
|
183
|
+
* @param fn: The predicate function to indicate if the option should remain `Some`
|
|
184
|
+
* @param option: The option to inspect
|
|
185
|
+
* @returns `Some(value)` if the variant was `Some` and the predicate returns `true` or `None` otherwise
|
|
186
|
+
*
|
|
187
|
+
* @since v0.2.0
|
|
188
|
+
*/
|
|
189
|
+
export let filter = (fn, option) => {
|
|
73
190
|
match (option) {
|
|
74
191
|
Some(x) =>
|
|
75
|
-
if (
|
|
192
|
+
if (fn(x)) {
|
|
76
193
|
Some(x)
|
|
77
194
|
} else {
|
|
78
195
|
None
|
|
@@ -81,70 +198,160 @@ let filter = (pred, option) => {
|
|
|
81
198
|
}
|
|
82
199
|
}
|
|
83
200
|
|
|
84
|
-
|
|
201
|
+
/**
|
|
202
|
+
* Combine two Options into a single Option containing a tuple of their values.
|
|
203
|
+
*
|
|
204
|
+
* @param optionA: The first option to combine
|
|
205
|
+
* @param optionB: The second option to combine
|
|
206
|
+
* @returns `Some((valueA, valueB))` if both Options are `Some` variants or `None` otherwise
|
|
207
|
+
*
|
|
208
|
+
* @since v0.2.0
|
|
209
|
+
*/
|
|
210
|
+
export let zip = (optionA, optionB) => {
|
|
85
211
|
match ((optionA, optionB)) {
|
|
86
212
|
(Some(a), Some(b)) => Some((a, b)),
|
|
87
213
|
_ => None
|
|
88
214
|
}
|
|
89
215
|
}
|
|
90
216
|
|
|
91
|
-
|
|
217
|
+
/**
|
|
218
|
+
* Combine two Options into a single Option. The new value is produced by applying the given function to both values.
|
|
219
|
+
*
|
|
220
|
+
* @param fn: The function to generate a new value
|
|
221
|
+
* @param optionA: The first option to combine
|
|
222
|
+
* @param optionB: The second option to combine
|
|
223
|
+
* @returns `Some(newValue)` if both Options are `Some` variants or `None` otherwise
|
|
224
|
+
*
|
|
225
|
+
* @since v0.2.0
|
|
226
|
+
*/
|
|
227
|
+
export let zipWith = (fn, optionA, optionB) => {
|
|
92
228
|
match ((optionA, optionB)) {
|
|
93
229
|
(Some(a), Some(b)) => Some(fn(a, b)),
|
|
94
230
|
_ => None
|
|
95
231
|
}
|
|
96
232
|
}
|
|
97
233
|
|
|
98
|
-
|
|
234
|
+
/**
|
|
235
|
+
* Flattens nested Options.
|
|
236
|
+
*
|
|
237
|
+
* @param option: The option to flatten
|
|
238
|
+
* @returns `Some(innerValue)` if all nested options were the `Some` variant or `None` otherwise
|
|
239
|
+
*
|
|
240
|
+
* @example Option.flatten(Some(Some(1))) == Some(1)
|
|
241
|
+
*
|
|
242
|
+
* @since v0.2.0
|
|
243
|
+
*/
|
|
244
|
+
export let flatten = (option) => {
|
|
99
245
|
match (option) {
|
|
100
246
|
Some(Some(x)) => Some(x),
|
|
101
247
|
_ => None
|
|
102
248
|
}
|
|
103
249
|
}
|
|
104
250
|
|
|
105
|
-
|
|
251
|
+
/**
|
|
252
|
+
* Converts an Option to a list with either zero or one item.
|
|
253
|
+
*
|
|
254
|
+
* @param option: The option to convert
|
|
255
|
+
* @returns `[value]` if the Option was the `Some` variant or `[]` otherwise
|
|
256
|
+
*
|
|
257
|
+
* @since v0.2.0
|
|
258
|
+
*/
|
|
259
|
+
export let toList = (option) => {
|
|
106
260
|
match (option) {
|
|
107
261
|
Some(x) => [x],
|
|
108
262
|
None => []
|
|
109
263
|
}
|
|
110
264
|
}
|
|
111
265
|
|
|
112
|
-
|
|
266
|
+
/**
|
|
267
|
+
* Converts an Option to an array with either zero or one item.
|
|
268
|
+
*
|
|
269
|
+
* @param option: The option to convert
|
|
270
|
+
* @returns `[> value]` if the Option was the `Some` variant or `[> ]` otherwise
|
|
271
|
+
*
|
|
272
|
+
* @since v0.2.0
|
|
273
|
+
*/
|
|
274
|
+
export let toArray = (option) => {
|
|
113
275
|
match (option) {
|
|
114
276
|
Some(x) => [> x],
|
|
115
277
|
None => [>]
|
|
116
278
|
}
|
|
117
279
|
}
|
|
118
280
|
|
|
119
|
-
|
|
281
|
+
/**
|
|
282
|
+
* Converts the Option to a Result, using the provided error in case of the `None` variant.
|
|
283
|
+
*
|
|
284
|
+
* @param err: The error to use if the option is `None`
|
|
285
|
+
* @param option: The option to convert
|
|
286
|
+
* @returns `Ok(value)` if the Option is `Some(value)` or `Err(err)` if the Option is `None`
|
|
287
|
+
*
|
|
288
|
+
* @since v0.2.0
|
|
289
|
+
*/
|
|
290
|
+
export let toResult = (err, option) => {
|
|
291
|
+
match (option) {
|
|
292
|
+
Some(a) => Ok(a),
|
|
293
|
+
None => Err(err)
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* If the Option is `Some(value)`, applies the `fn` function to the `value` without producing a new value.
|
|
299
|
+
*
|
|
300
|
+
* @param fn: The function to call on the value of a `Some` variant
|
|
301
|
+
* @param option: The option to inspect
|
|
302
|
+
*
|
|
303
|
+
* @since v0.2.0
|
|
304
|
+
*/
|
|
305
|
+
export let sideEffect = (fn, option) => {
|
|
120
306
|
match (option) {
|
|
121
307
|
Some(x) => fn(x),
|
|
122
308
|
None => void
|
|
123
309
|
}
|
|
124
310
|
}
|
|
125
311
|
|
|
126
|
-
|
|
312
|
+
/**
|
|
313
|
+
* If the Option is `Some(value)`, applies the `fn` function to the `value` without producing a new value.
|
|
314
|
+
* Useful for inspecting Options without changing anything.
|
|
315
|
+
*
|
|
316
|
+
* @param fn: The function to call on the value of a `Some` variant
|
|
317
|
+
* @param option: The option to inspect
|
|
318
|
+
* @returns The unmodified option
|
|
319
|
+
*
|
|
320
|
+
* @since v0.2.0
|
|
321
|
+
*/
|
|
322
|
+
export let peek = (fn, option) => {
|
|
127
323
|
sideEffect(fn, option)
|
|
128
324
|
option
|
|
129
325
|
}
|
|
130
326
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
327
|
+
/**
|
|
328
|
+
* Behaves like a logical OR (`||`) where the first Option is only returned if it is the `Some` variant and falling back to the second Option in all other cases.
|
|
329
|
+
*
|
|
330
|
+
* @param optionA: The first option
|
|
331
|
+
* @param optionB: The second option
|
|
332
|
+
* @returns The first Option if it is the `Some` variant or the second Option otherwise
|
|
333
|
+
*
|
|
334
|
+
* @since v0.2.0
|
|
335
|
+
*/
|
|
336
|
+
export let or = (optionA, optionB) => {
|
|
337
|
+
match (optionA) {
|
|
338
|
+
Some(x) => optionA,
|
|
339
|
+
None => optionB
|
|
135
340
|
}
|
|
136
341
|
}
|
|
137
342
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
343
|
+
/**
|
|
344
|
+
* Behaves like a logical AND (`&&`) where the first Option is only returned if it is the `None` variant and falling back to the second Option Result in all other cases.
|
|
345
|
+
*
|
|
346
|
+
* @param optionA: The first option
|
|
347
|
+
* @param optionB: The second option
|
|
348
|
+
* @returns The second Option if both are the `Some` variant or the first Option otherwise
|
|
349
|
+
*
|
|
350
|
+
* @since v0.2.0
|
|
351
|
+
*/
|
|
352
|
+
export let and = (optionA, optionB) => {
|
|
353
|
+
match (optionA) {
|
|
354
|
+
Some(_) => optionB,
|
|
355
|
+
None => optionA
|
|
149
356
|
}
|
|
150
357
|
}
|