@grain/stdlib 0.5.2 → 0.5.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.
Files changed (54) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/array.gr +61 -1
  3. package/array.md +113 -0
  4. package/bigint.md +30 -30
  5. package/buffer.gr +24 -22
  6. package/char.gr +2 -2
  7. package/float32.md +3 -3
  8. package/float64.md +3 -3
  9. package/immutablemap.gr +493 -0
  10. package/immutablemap.md +479 -0
  11. package/immutablepriorityqueue.gr +360 -0
  12. package/immutablepriorityqueue.md +291 -0
  13. package/immutableset.gr +498 -0
  14. package/immutableset.md +449 -0
  15. package/list.gr +75 -2
  16. package/list.md +110 -0
  17. package/map.gr +1 -2
  18. package/marshal.gr +1058 -0
  19. package/marshal.md +76 -0
  20. package/number.gr +689 -23
  21. package/number.md +362 -27
  22. package/package.json +1 -1
  23. package/pervasives.gr +16 -5
  24. package/pervasives.md +28 -0
  25. package/priorityqueue.gr +261 -0
  26. package/priorityqueue.md +309 -0
  27. package/queue.gr +14 -1
  28. package/queue.md +16 -1
  29. package/regex.gr +90 -67
  30. package/runtime/bigint.gr +4 -4
  31. package/runtime/compare.gr +179 -0
  32. package/runtime/compare.md +6 -0
  33. package/runtime/equal.gr +3 -3
  34. package/runtime/exception.gr +9 -5
  35. package/runtime/exception.md +8 -2
  36. package/runtime/gc.gr +2 -1
  37. package/runtime/malloc.gr +1 -3
  38. package/runtime/numberUtils.gr +11 -11
  39. package/runtime/numbers.gr +423 -100
  40. package/runtime/numbers.md +50 -0
  41. package/runtime/string.gr +4 -2
  42. package/set.gr +26 -27
  43. package/stack.gr +12 -0
  44. package/stack.md +15 -0
  45. package/string.gr +409 -53
  46. package/string.md +164 -1
  47. package/sys/file.gr +4 -4
  48. package/sys/file.md +3 -3
  49. package/sys/process.gr +3 -3
  50. package/sys/process.md +3 -3
  51. package/sys/random.gr +2 -2
  52. package/sys/random.md +2 -2
  53. package/sys/time.gr +2 -2
  54. package/sys/time.md +2 -2
@@ -0,0 +1,261 @@
1
+ /**
2
+ * @module PriorityQueue: A mutable priority queue implementation. A priority queue is a data structure that maintains elements in a priority order. Elements with higher priority are served before elements with lower priority when extracting from the priority queue.
3
+ *
4
+ * @example import PriorityQueue from "priorityqueue"
5
+ *
6
+ * @since v0.5.3
7
+ */
8
+
9
+ import Array from "array"
10
+ import List from "list"
11
+ import Number from "number"
12
+ import Option from "option"
13
+
14
+ /**
15
+ * @section Types: Type declarations included in the PriorityQueue module.
16
+ */
17
+
18
+ /**
19
+ * Mutable data structure which maintains a priority order for its elements.
20
+ */
21
+ record PriorityQueue<a> {
22
+ mut size: Number,
23
+ mut array: Array<Option<a>>,
24
+ comp: (a, a) -> Number,
25
+ }
26
+
27
+ /**
28
+ * @section Values: Functions for working with PriorityQueues.
29
+ */
30
+
31
+ let swap = (i1, i2, array) => {
32
+ let t = array[i2]
33
+ array[i2] = array[i1]
34
+ array[i1] = t
35
+ }
36
+
37
+ let get = (array, i) =>
38
+ Option.expect(
39
+ "Impossible: " ++
40
+ toString(i) ++
41
+ " in PriorityQueue's inner storage array is None",
42
+ array[i]
43
+ )
44
+
45
+ let rec siftDown = (i, pq) => {
46
+ let leftI = 2 * i + 1
47
+ let rightI = 2 * i + 2
48
+
49
+ // we want to find the smaller child from the current tree node to sift down to
50
+ let mut swapWithI = i
51
+ if (leftI < pq.size && pq.comp(get(pq.array, leftI), get(pq.array, i)) < 0) {
52
+ swapWithI = leftI
53
+ }
54
+ if (
55
+ rightI < pq.size &&
56
+ pq.comp(get(pq.array, rightI), get(pq.array, swapWithI)) < 0
57
+ ) {
58
+ swapWithI = rightI
59
+ }
60
+ if (swapWithI != i) {
61
+ swap(i, swapWithI, pq.array)
62
+ siftDown(swapWithI, pq)
63
+ }
64
+ }
65
+
66
+ let rec siftUp = (i, pq) => {
67
+ let parentI = Number.trunc((i - 1) / 2)
68
+ // we should only sift up if the element is smaller than its parent
69
+ if (i > 0 && pq.comp(get(pq.array, i), get(pq.array, parentI)) < 0) {
70
+ swap(i, parentI, pq.array)
71
+ siftUp(parentI, pq)
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Creates a new priority queue with a given internal storage size and a
77
+ * comparator function, which is used to determine priority of elements. The
78
+ * comparator function takes two elements and must return 0 if both share
79
+ * priority, a positive number if the first has greater priority, and a
80
+ * negative number if the first has less priority.
81
+ *
82
+ * Generally, you won't need to care about the storage size of your priority
83
+ * queue and can use `PriorityQueue.make()` instead.
84
+ *
85
+ * @param size: The initial storage size of the priority queue
86
+ * @param comp: The comparator function used to indicate priority order
87
+ * @returns An empty priority queue
88
+ *
89
+ * @since v0.5.3
90
+ */
91
+ export let makeSized = (size, comp) => {
92
+ { size: 0, array: Array.make(size, None), comp }
93
+ }
94
+
95
+ /**
96
+ * Creates a new priority queue with a comparator function, which is used to
97
+ * determine priority of elements. The comparator function takes two elements
98
+ * and must return 0 if both share priority, a positive number if the first
99
+ * has greater priority, and a negative number if the first has less priority.
100
+ *
101
+ * @param comp: The comparator function used to indicate priority order
102
+ * @returns An empty priority queue
103
+ *
104
+ * @example PriorityQueue.make(compare) // creates a min priority queue of numbers using the compare pervasive
105
+ * @example PriorityQueue.make((a, b) => String.length(b) - String.length(a)) // creates a priority queue by string length (longest to shortest)
106
+ *
107
+ * @since v0.5.3
108
+ */
109
+ export let make = comp => {
110
+ makeSized(16, comp)
111
+ }
112
+
113
+ /**
114
+ * Gets the number of elements in a priority queue.
115
+ *
116
+ * @param pq: The priority queue to inspect
117
+ * @returns The number of elements in the priority queue
118
+ *
119
+ * @since v0.5.3
120
+ */
121
+ export let size = pq => {
122
+ pq.size
123
+ }
124
+
125
+ /**
126
+ * Determines if the priority queue contains no elements.
127
+ *
128
+ * @param pq: The priority queue to check
129
+ * @returns `true` if the priority queue is empty and `false` otherwise
130
+ *
131
+ * @since v0.5.3
132
+ */
133
+ export let isEmpty = pq => {
134
+ pq.size == 0
135
+ }
136
+
137
+ /**
138
+ * Adds a new element to the priority queue.
139
+ *
140
+ * @param val: The value to add into the priority queue
141
+ * @param pq: The priority queue to update
142
+ *
143
+ * @since v0.5.3
144
+ */
145
+ export let push = (val, pq) => {
146
+ let arrLen = Array.length(pq.array)
147
+ // double size of internal array if out of space
148
+ if (pq.size == arrLen) {
149
+ let oldArr = pq.array
150
+ pq.array = Array.make(arrLen * 2, None)
151
+ Array.forEachi((val, i) => {
152
+ pq.array[i] = val
153
+ }, oldArr)
154
+ }
155
+ pq.array[pq.size] = Some(val)
156
+ pq.size += 1
157
+ // reorder heap to ensure that binary heap property of parent nodes having
158
+ // larger values than their children is upheld
159
+ siftUp(pq.size - 1, pq)
160
+ }
161
+
162
+ /**
163
+ * Retrieves the highest priority element in the priority queue. It is not
164
+ * removed from the queue.
165
+ *
166
+ * @param pq: The priority queue to inspect
167
+ * @returns `Some(value)` containing the highest priority element or `None` if the priority queue is empty
168
+ *
169
+ * @since v0.5.3
170
+ */
171
+ export let peek = pq => {
172
+ if (pq.size == 0) {
173
+ None
174
+ } else {
175
+ pq.array[0]
176
+ }
177
+ }
178
+
179
+ /**
180
+ * Removes and retrieves the highest priority element in the priority queue.
181
+ *
182
+ * @param pq: The priority queue to inspect
183
+ * @returns `Some(value)` containing the highest priority element or `None` if the priority queue is empty
184
+ *
185
+ * @since v0.5.3
186
+ */
187
+ export let pop = pq => {
188
+ if (pq.size == 0) {
189
+ None
190
+ } else {
191
+ let root = pq.array[0]
192
+
193
+ pq.array[0] = pq.array[pq.size - 1]
194
+ pq.array[pq.size - 1] = None
195
+ pq.size -= 1
196
+ // reorder heap to ensure that binary heap property of parent nodes having
197
+ // larger values than their children is upheld
198
+ siftDown(0, pq)
199
+ root
200
+ }
201
+ }
202
+
203
+ /**
204
+ * Clears the priority queue and produces a list of all of the elements in the priority
205
+ * queue in priority order.
206
+ *
207
+ * @param pq: The priority queue to drain
208
+ * @returns A list of all elements in the priority in priority order
209
+ *
210
+ * @since v0.5.3
211
+ */
212
+ export let drain = pq => {
213
+ let rec drainRec = acc => {
214
+ match (pop(pq)) {
215
+ Some(val) => drainRec([val, ...acc]),
216
+ None => acc,
217
+ }
218
+ }
219
+ List.reverse(drainRec([]))
220
+ }
221
+
222
+ /**
223
+ * Constructs a new priority queue initialized with the elements in the array
224
+ * using a custom comparator function, which is used to determine priority of
225
+ * elements. The comparator function takes two elements and must return 0 if
226
+ * both share priority, a positive number if the first has greater priority,
227
+ * and a negative number if the first has less priority.
228
+ *
229
+ * @param array: An array of values used to initialize the priority queue
230
+ * @param comp: A comparator function used to assign priority to elements
231
+ * @returns A priority queue containing the elements from the array
232
+ *
233
+ * @since v0.5.4
234
+ */
235
+ export let fromArray = (array, comp) => {
236
+ let size = Array.length(array)
237
+ let array = Array.map(x => Some(x), array)
238
+ let heap = { size, array, comp }
239
+ for (let mut i = size - 1; i >= 0; i -= 1) {
240
+ siftDown(i, heap)
241
+ }
242
+ heap
243
+ }
244
+
245
+ /**
246
+ * Constructs a new priority queue initialized with the elements in the list
247
+ * using a custom comparator function, which is used to determine priority of
248
+ * elements. The comparator function takes two elements and must return 0 if
249
+ * both share priority, a positive number if the first has greater priority,
250
+ * and a negative number if the first has less priority.
251
+ *
252
+ * @param list: A list of values used to initialize the priority queue
253
+ * @param comp: A comparator function used to assign priority to elements
254
+ * @returns A priority queue containing the elements from the list
255
+ *
256
+ * @since v0.5.3
257
+ */
258
+ export let fromList = (list, comp) => {
259
+ let array = Array.fromList(list)
260
+ fromArray(array, comp)
261
+ }
@@ -0,0 +1,309 @@
1
+ ---
2
+ title: PriorityQueue
3
+ ---
4
+
5
+ A mutable priority queue implementation. A priority queue is a data structure that maintains elements in a priority order. Elements with higher priority are served before elements with lower priority when extracting from the priority queue.
6
+
7
+ <details disabled>
8
+ <summary tabindex="-1">Added in <code>0.5.3</code></summary>
9
+ No other changes yet.
10
+ </details>
11
+
12
+ ```grain
13
+ import PriorityQueue from "priorityqueue"
14
+ ```
15
+
16
+ ## Types
17
+
18
+ Type declarations included in the PriorityQueue module.
19
+
20
+ ### PriorityQueue.**PriorityQueue**
21
+
22
+ ```grain
23
+ type PriorityQueue<a>
24
+ ```
25
+
26
+ Mutable data structure which maintains a priority order for its elements.
27
+
28
+ ## Values
29
+
30
+ Functions for working with PriorityQueues.
31
+
32
+ ### PriorityQueue.**makeSized**
33
+
34
+ <details disabled>
35
+ <summary tabindex="-1">Added in <code>0.5.3</code></summary>
36
+ No other changes yet.
37
+ </details>
38
+
39
+ ```grain
40
+ makeSized : (Number, ((a, a) -> Number)) -> PriorityQueue<a>
41
+ ```
42
+
43
+ Creates a new priority queue with a given internal storage size and a
44
+ comparator function, which is used to determine priority of elements. The
45
+ comparator function takes two elements and must return 0 if both share
46
+ priority, a positive number if the first has greater priority, and a
47
+ negative number if the first has less priority.
48
+
49
+ Generally, you won't need to care about the storage size of your priority
50
+ queue and can use `PriorityQueue.make()` instead.
51
+
52
+ Parameters:
53
+
54
+ |param|type|description|
55
+ |-----|----|-----------|
56
+ |`size`|`Number`|The initial storage size of the priority queue|
57
+ |`comp`|`(a, a) -> Number`|The comparator function used to indicate priority order|
58
+
59
+ Returns:
60
+
61
+ |type|description|
62
+ |----|-----------|
63
+ |`PriorityQueue<a>`|An empty priority queue|
64
+
65
+ ### PriorityQueue.**make**
66
+
67
+ <details disabled>
68
+ <summary tabindex="-1">Added in <code>0.5.3</code></summary>
69
+ No other changes yet.
70
+ </details>
71
+
72
+ ```grain
73
+ make : ((a, a) -> Number) -> PriorityQueue<a>
74
+ ```
75
+
76
+ Creates a new priority queue with a comparator function, which is used to
77
+ determine priority of elements. The comparator function takes two elements
78
+ and must return 0 if both share priority, a positive number if the first
79
+ has greater priority, and a negative number if the first has less priority.
80
+
81
+ Parameters:
82
+
83
+ |param|type|description|
84
+ |-----|----|-----------|
85
+ |`comp`|`(a, a) -> Number`|The comparator function used to indicate priority order|
86
+
87
+ Returns:
88
+
89
+ |type|description|
90
+ |----|-----------|
91
+ |`PriorityQueue<a>`|An empty priority queue|
92
+
93
+ Examples:
94
+
95
+ ```grain
96
+ PriorityQueue.make(compare) // creates a min priority queue of numbers using the compare pervasive
97
+ ```
98
+
99
+ ```grain
100
+ PriorityQueue.make((a, b) => String.length(b) - String.length(a)) // creates a priority queue by string length (longest to shortest)
101
+ ```
102
+
103
+ ### PriorityQueue.**size**
104
+
105
+ <details disabled>
106
+ <summary tabindex="-1">Added in <code>0.5.3</code></summary>
107
+ No other changes yet.
108
+ </details>
109
+
110
+ ```grain
111
+ size : PriorityQueue<a> -> Number
112
+ ```
113
+
114
+ Gets the number of elements in a priority queue.
115
+
116
+ Parameters:
117
+
118
+ |param|type|description|
119
+ |-----|----|-----------|
120
+ |`pq`|`PriorityQueue<a>`|The priority queue to inspect|
121
+
122
+ Returns:
123
+
124
+ |type|description|
125
+ |----|-----------|
126
+ |`Number`|The number of elements in the priority queue|
127
+
128
+ ### PriorityQueue.**isEmpty**
129
+
130
+ <details disabled>
131
+ <summary tabindex="-1">Added in <code>0.5.3</code></summary>
132
+ No other changes yet.
133
+ </details>
134
+
135
+ ```grain
136
+ isEmpty : PriorityQueue<a> -> Bool
137
+ ```
138
+
139
+ Determines if the priority queue contains no elements.
140
+
141
+ Parameters:
142
+
143
+ |param|type|description|
144
+ |-----|----|-----------|
145
+ |`pq`|`PriorityQueue<a>`|The priority queue to check|
146
+
147
+ Returns:
148
+
149
+ |type|description|
150
+ |----|-----------|
151
+ |`Bool`|`true` if the priority queue is empty and `false` otherwise|
152
+
153
+ ### PriorityQueue.**push**
154
+
155
+ <details disabled>
156
+ <summary tabindex="-1">Added in <code>0.5.3</code></summary>
157
+ No other changes yet.
158
+ </details>
159
+
160
+ ```grain
161
+ push : (a, PriorityQueue<a>) -> Void
162
+ ```
163
+
164
+ Adds a new element to the priority queue.
165
+
166
+ Parameters:
167
+
168
+ |param|type|description|
169
+ |-----|----|-----------|
170
+ |`val`|`a`|The value to add into the priority queue|
171
+ |`pq`|`PriorityQueue<a>`|The priority queue to update|
172
+
173
+ ### PriorityQueue.**peek**
174
+
175
+ <details disabled>
176
+ <summary tabindex="-1">Added in <code>0.5.3</code></summary>
177
+ No other changes yet.
178
+ </details>
179
+
180
+ ```grain
181
+ peek : PriorityQueue<a> -> Option<a>
182
+ ```
183
+
184
+ Retrieves the highest priority element in the priority queue. It is not
185
+ removed from the queue.
186
+
187
+ Parameters:
188
+
189
+ |param|type|description|
190
+ |-----|----|-----------|
191
+ |`pq`|`PriorityQueue<a>`|The priority queue to inspect|
192
+
193
+ Returns:
194
+
195
+ |type|description|
196
+ |----|-----------|
197
+ |`Option<a>`|`Some(value)` containing the highest priority element or `None` if the priority queue is empty|
198
+
199
+ ### PriorityQueue.**pop**
200
+
201
+ <details disabled>
202
+ <summary tabindex="-1">Added in <code>0.5.3</code></summary>
203
+ No other changes yet.
204
+ </details>
205
+
206
+ ```grain
207
+ pop : PriorityQueue<a> -> Option<a>
208
+ ```
209
+
210
+ Removes and retrieves the highest priority element in the priority queue.
211
+
212
+ Parameters:
213
+
214
+ |param|type|description|
215
+ |-----|----|-----------|
216
+ |`pq`|`PriorityQueue<a>`|The priority queue to inspect|
217
+
218
+ Returns:
219
+
220
+ |type|description|
221
+ |----|-----------|
222
+ |`Option<a>`|`Some(value)` containing the highest priority element or `None` if the priority queue is empty|
223
+
224
+ ### PriorityQueue.**drain**
225
+
226
+ <details disabled>
227
+ <summary tabindex="-1">Added in <code>0.5.3</code></summary>
228
+ No other changes yet.
229
+ </details>
230
+
231
+ ```grain
232
+ drain : PriorityQueue<a> -> List<a>
233
+ ```
234
+
235
+ Clears the priority queue and produces a list of all of the elements in the priority
236
+ queue in priority order.
237
+
238
+ Parameters:
239
+
240
+ |param|type|description|
241
+ |-----|----|-----------|
242
+ |`pq`|`PriorityQueue<a>`|The priority queue to drain|
243
+
244
+ Returns:
245
+
246
+ |type|description|
247
+ |----|-----------|
248
+ |`List<a>`|A list of all elements in the priority in priority order|
249
+
250
+ ### PriorityQueue.**fromArray**
251
+
252
+ <details disabled>
253
+ <summary tabindex="-1">Added in <code>0.5.4</code></summary>
254
+ No other changes yet.
255
+ </details>
256
+
257
+ ```grain
258
+ fromArray : (Array<a>, ((a, a) -> Number)) -> PriorityQueue<a>
259
+ ```
260
+
261
+ Constructs a new priority queue initialized with the elements in the array
262
+ using a custom comparator function, which is used to determine priority of
263
+ elements. The comparator function takes two elements and must return 0 if
264
+ both share priority, a positive number if the first has greater priority,
265
+ and a negative number if the first has less priority.
266
+
267
+ Parameters:
268
+
269
+ |param|type|description|
270
+ |-----|----|-----------|
271
+ |`array`|`Array<a>`|An array of values used to initialize the priority queue|
272
+ |`comp`|`(a, a) -> Number`|A comparator function used to assign priority to elements|
273
+
274
+ Returns:
275
+
276
+ |type|description|
277
+ |----|-----------|
278
+ |`PriorityQueue<a>`|A priority queue containing the elements from the array|
279
+
280
+ ### PriorityQueue.**fromList**
281
+
282
+ <details disabled>
283
+ <summary tabindex="-1">Added in <code>0.5.3</code></summary>
284
+ No other changes yet.
285
+ </details>
286
+
287
+ ```grain
288
+ fromList : (List<a>, ((a, a) -> Number)) -> PriorityQueue<a>
289
+ ```
290
+
291
+ Constructs a new priority queue initialized with the elements in the list
292
+ using a custom comparator function, which is used to determine priority of
293
+ elements. The comparator function takes two elements and must return 0 if
294
+ both share priority, a positive number if the first has greater priority,
295
+ and a negative number if the first has less priority.
296
+
297
+ Parameters:
298
+
299
+ |param|type|description|
300
+ |-----|----|-----------|
301
+ |`list`|`List<a>`|A list of values used to initialize the priority queue|
302
+ |`comp`|`(a, a) -> Number`|A comparator function used to assign priority to elements|
303
+
304
+ Returns:
305
+
306
+ |type|description|
307
+ |----|-----------|
308
+ |`PriorityQueue<a>`|A priority queue containing the elements from the list|
309
+
package/queue.gr CHANGED
@@ -15,13 +15,26 @@ record Queue<a> {
15
15
  }
16
16
 
17
17
  /**
18
- * @section Values: Functions for working with queues.
18
+ * @section Values: Functions and constants for working with queues.
19
19
  */
20
20
 
21
+ /**
22
+ * An empty queue.
23
+ *
24
+ * @since v0.5.4
25
+ */
26
+ export let empty = {
27
+ let empty = { forwards: [], backwards: [] }
28
+ empty
29
+ }
30
+
21
31
  /**
22
32
  * Creates an empty queue.
23
33
  *
24
34
  * @returns An empty queue
35
+ *
36
+ * @deprecated This will be removed in the v0.6.0 release of Grain.
37
+ *
25
38
  * @since v0.2.0
26
39
  */
27
40
  export let make = () => {
package/queue.md CHANGED
@@ -25,10 +25,25 @@ type Queue<a>
25
25
 
26
26
  ## Values
27
27
 
28
- Functions for working with queues.
28
+ Functions and constants for working with queues.
29
+
30
+ ### Queue.**empty**
31
+
32
+ <details disabled>
33
+ <summary tabindex="-1">Added in <code>0.5.4</code></summary>
34
+ No other changes yet.
35
+ </details>
36
+
37
+ ```grain
38
+ empty : Queue<a>
39
+ ```
40
+
41
+ An empty queue.
29
42
 
30
43
  ### Queue.**make**
31
44
 
45
+ > **Deprecated:** This will be removed in the v0.6.0 release of Grain.
46
+
32
47
  <details disabled>
33
48
  <summary tabindex="-1">Added in <code>0.2.0</code></summary>
34
49
  No other changes yet.