@grain/stdlib 0.4.0 → 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 +65 -0
- package/LICENSE +21 -0
- package/README.md +34 -0
- package/array.gr +136 -44
- package/array.md +97 -21
- package/buffer.gr +495 -424
- package/buffer.md +850 -0
- package/bytes.gr +512 -407
- package/bytes.md +621 -0
- package/char.gr +11 -3
- package/hash.gr +26 -3
- package/hash.md +44 -0
- package/list.gr +54 -0
- package/number.gr +24 -6
- package/number.md +49 -17
- package/option.gr +244 -37
- package/option.md +579 -0
- package/package.json +33 -29
- package/queue.gr +98 -29
- package/queue.md +191 -0
- package/range.md +1 -1
- package/regex.gr +3055 -0
- package/regex.md +449 -0
- package/result.gr +216 -70
- package/result.md +446 -0
- package/runtime/gc.gr +2 -2
- package/runtime/string.gr +56 -24
- package/runtime/stringUtils.gr +172 -0
- package/runtime/unsafe/conv.gr +43 -0
- package/set.gr +172 -5
- package/set.md +502 -0
- package/stack.md +143 -0
- package/string.gr +444 -230
- package/string.md +815 -0
- package/sys/file.gr +3 -2
- package/sys/file.md +2 -2
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
|
}
|