effect 2.0.3 → 2.0.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 (112) hide show
  1. package/FiberMap/package.json +6 -0
  2. package/FiberSet/package.json +6 -0
  3. package/Trie/package.json +6 -0
  4. package/dist/cjs/FiberMap.js +176 -0
  5. package/dist/cjs/FiberMap.js.map +1 -0
  6. package/dist/cjs/FiberSet.js +150 -0
  7. package/dist/cjs/FiberSet.js.map +1 -0
  8. package/dist/cjs/MutableHashMap.js +11 -1
  9. package/dist/cjs/MutableHashMap.js.map +1 -1
  10. package/dist/cjs/MutableHashSet.js +7 -1
  11. package/dist/cjs/MutableHashSet.js.map +1 -1
  12. package/dist/cjs/MutableList.js +8 -11
  13. package/dist/cjs/MutableList.js.map +1 -1
  14. package/dist/cjs/Schedule.js.map +1 -1
  15. package/dist/cjs/Struct.js +16 -1
  16. package/dist/cjs/Struct.js.map +1 -1
  17. package/dist/cjs/Trie.js +680 -0
  18. package/dist/cjs/Trie.js.map +1 -0
  19. package/dist/cjs/index.js +8 -2
  20. package/dist/cjs/index.js.map +1 -1
  21. package/dist/cjs/internal/hashMap/node.js +2 -2
  22. package/dist/cjs/internal/hashMap/node.js.map +1 -1
  23. package/dist/cjs/internal/pubsub.js +11 -17
  24. package/dist/cjs/internal/pubsub.js.map +1 -1
  25. package/dist/cjs/internal/redBlackTree/node.js +35 -30
  26. package/dist/cjs/internal/redBlackTree/node.js.map +1 -1
  27. package/dist/cjs/internal/redBlackTree.js +69 -13
  28. package/dist/cjs/internal/redBlackTree.js.map +1 -1
  29. package/dist/cjs/internal/schedule.js +1 -1
  30. package/dist/cjs/internal/schedule.js.map +1 -1
  31. package/dist/cjs/internal/stack.js +6 -11
  32. package/dist/cjs/internal/stack.js.map +1 -1
  33. package/dist/cjs/internal/trie.js +588 -0
  34. package/dist/cjs/internal/trie.js.map +1 -0
  35. package/dist/cjs/internal/version.js +1 -1
  36. package/dist/dts/FiberMap.d.ts +125 -0
  37. package/dist/dts/FiberMap.d.ts.map +1 -0
  38. package/dist/dts/FiberSet.d.ts +99 -0
  39. package/dist/dts/FiberSet.d.ts.map +1 -0
  40. package/dist/dts/MutableHashMap.d.ts +4 -0
  41. package/dist/dts/MutableHashMap.d.ts.map +1 -1
  42. package/dist/dts/MutableHashSet.d.ts +5 -0
  43. package/dist/dts/MutableHashSet.d.ts.map +1 -1
  44. package/dist/dts/MutableList.d.ts.map +1 -1
  45. package/dist/dts/Schedule.d.ts +2 -1
  46. package/dist/dts/Schedule.d.ts.map +1 -1
  47. package/dist/dts/Struct.d.ts +17 -3
  48. package/dist/dts/Struct.d.ts.map +1 -1
  49. package/dist/dts/Trie.d.ts +740 -0
  50. package/dist/dts/Trie.d.ts.map +1 -0
  51. package/dist/dts/Types.d.ts +4 -0
  52. package/dist/dts/Types.d.ts.map +1 -1
  53. package/dist/dts/index.d.ts +26 -0
  54. package/dist/dts/index.d.ts.map +1 -1
  55. package/dist/dts/internal/redBlackTree/node.d.ts +8 -0
  56. package/dist/dts/internal/redBlackTree/node.d.ts.map +1 -1
  57. package/dist/dts/internal/stack.d.ts +1 -1
  58. package/dist/dts/internal/stack.d.ts.map +1 -1
  59. package/dist/dts/internal/trie.d.ts +2 -0
  60. package/dist/dts/internal/trie.d.ts.map +1 -0
  61. package/dist/dts/internal/version.d.ts +1 -1
  62. package/dist/esm/FiberMap.js +140 -0
  63. package/dist/esm/FiberMap.js.map +1 -0
  64. package/dist/esm/FiberSet.js +114 -0
  65. package/dist/esm/FiberSet.js.map +1 -0
  66. package/dist/esm/MutableHashMap.js +9 -0
  67. package/dist/esm/MutableHashMap.js.map +1 -1
  68. package/dist/esm/MutableHashSet.js +5 -0
  69. package/dist/esm/MutableHashSet.js.map +1 -1
  70. package/dist/esm/MutableList.js +8 -11
  71. package/dist/esm/MutableList.js.map +1 -1
  72. package/dist/esm/Schedule.js.map +1 -1
  73. package/dist/esm/Struct.js +14 -0
  74. package/dist/esm/Struct.js.map +1 -1
  75. package/dist/esm/Trie.js +648 -0
  76. package/dist/esm/Trie.js.map +1 -0
  77. package/dist/esm/index.js +26 -0
  78. package/dist/esm/index.js.map +1 -1
  79. package/dist/esm/internal/hashMap/node.js +2 -2
  80. package/dist/esm/internal/hashMap/node.js.map +1 -1
  81. package/dist/esm/internal/pubsub.js +11 -17
  82. package/dist/esm/internal/pubsub.js.map +1 -1
  83. package/dist/esm/internal/redBlackTree/node.js +31 -25
  84. package/dist/esm/internal/redBlackTree/node.js.map +1 -1
  85. package/dist/esm/internal/redBlackTree.js +69 -13
  86. package/dist/esm/internal/redBlackTree.js.map +1 -1
  87. package/dist/esm/internal/schedule.js +1 -1
  88. package/dist/esm/internal/schedule.js.map +1 -1
  89. package/dist/esm/internal/stack.js +4 -9
  90. package/dist/esm/internal/stack.js.map +1 -1
  91. package/dist/esm/internal/trie.js +547 -0
  92. package/dist/esm/internal/trie.js.map +1 -0
  93. package/dist/esm/internal/version.js +1 -1
  94. package/package.json +25 -1
  95. package/src/FiberMap.ts +269 -0
  96. package/src/FiberSet.ts +194 -0
  97. package/src/MutableHashMap.ts +10 -0
  98. package/src/MutableHashSet.ts +6 -0
  99. package/src/MutableList.ts +15 -7
  100. package/src/Schedule.ts +2 -1
  101. package/src/Struct.ts +24 -6
  102. package/src/Trie.ts +772 -0
  103. package/src/Types.ts +5 -0
  104. package/src/index.ts +29 -0
  105. package/src/internal/hashMap/node.ts +3 -3
  106. package/src/internal/pubsub.ts +15 -14
  107. package/src/internal/redBlackTree/node.ts +37 -17
  108. package/src/internal/redBlackTree.ts +73 -38
  109. package/src/internal/schedule.ts +2 -2
  110. package/src/internal/stack.ts +8 -2
  111. package/src/internal/trie.ts +721 -0
  112. package/src/internal/version.ts +1 -1
package/src/Trie.ts ADDED
@@ -0,0 +1,772 @@
1
+ /**
2
+ * A `Trie` is used for locating specific `string` keys from within a set.
3
+ *
4
+ * It works similar to `HashMap`, but with keys required to be `string`.
5
+ * This constraint unlocks some performance optimizations and new methods to get string prefixes (e.g. `keysWithPrefix`, `longestPrefixOf`).
6
+ *
7
+ * Prefix search is also the main feature that makes a `Trie` more suited than `HashMap` for certain usecases.
8
+ *
9
+ * A `Trie` is often used to store a dictionary (list of words) that can be searched
10
+ * in a manner that allows for efficient generation of completion lists
11
+ * (e.g. predict the rest of a word a user is typing).
12
+ *
13
+ * A `Trie` has O(n) lookup time where `n` is the size of the key,
14
+ * or even less than `n` on search misses.
15
+ *
16
+ * @since 2.0.0
17
+ */
18
+ import type { Equal } from "./Equal.js"
19
+ import type { Inspectable } from "./Inspectable.js"
20
+ import * as TR from "./internal/trie.js"
21
+ import type { Option } from "./Option.js"
22
+ import type { Pipeable } from "./Pipeable.js"
23
+ import type * as Types from "./Types.js"
24
+
25
+ const TypeId: unique symbol = TR.TrieTypeId as TypeId
26
+
27
+ /**
28
+ * @since 2.0.0
29
+ * @category symbol
30
+ */
31
+ export type TypeId = typeof TypeId
32
+
33
+ /**
34
+ * @since 2.0.0
35
+ * @category models
36
+ */
37
+ export interface Trie<in out Value> extends Iterable<[string, Value]>, Equal, Pipeable, Inspectable {
38
+ readonly [TypeId]: {
39
+ readonly _Value: Types.Covariant<Value>
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Creates an empty `Trie`.
45
+ *
46
+ * @example
47
+ * import * as Trie from "effect/Trie"
48
+ * import * as Equal from "effect/Equal"
49
+ *
50
+ * const trie = Trie.empty<string>()
51
+ *
52
+ * assert.equal(Trie.size(trie), 0)
53
+ * assert.deepStrictEqual(Array.from(trie), [])
54
+ *
55
+ * @since 2.0.0
56
+ * @category constructors
57
+ */
58
+ export const empty: <V = never>() => Trie<V> = TR.empty
59
+
60
+ /**
61
+ * Creates a new `Trie` from an iterable collection of key/value pairs (e.g. `Array<[string, V]>`).
62
+ *
63
+ * @example
64
+ * import * as Trie from "effect/Trie"
65
+ * import * as Equal from "effect/Equal"
66
+ *
67
+ * const iterable: Array<readonly [string, number]> = [["call", 0], ["me", 1], ["mind", 2], ["mid", 3]]
68
+ * const trie = Trie.fromIterable(iterable)
69
+ *
70
+ * // The entries in the `Trie` are extracted in alphabetical order, regardless of the insertion order
71
+ * assert.deepStrictEqual(Array.from(trie), [["call", 0], ["me", 1], ["mid", 3], ["mind", 2]])
72
+ * assert.equal(Equal.equals(Trie.make(["call", 0], ["me", 1], ["mind", 2], ["mid", 3]), trie), true)
73
+ *
74
+ * @since 2.0.0
75
+ * @category constructors
76
+ */
77
+ export const fromIterable: <V>(entries: Iterable<readonly [string, V]>) => Trie<V> = TR.fromIterable
78
+
79
+ /**
80
+ * Constructs a new `Trie` from the specified entries (`[string, V]`).
81
+ *
82
+ * @example
83
+ * import * as Trie from "effect/Trie"
84
+ * import * as Equal from "effect/Equal"
85
+ *
86
+ * const trie = Trie.make(["ca", 0], ["me", 1])
87
+ *
88
+ * assert.deepStrictEqual(Array.from(trie), [["ca", 0], ["me", 1]])
89
+ * assert.equal(Equal.equals(Trie.fromIterable([["ca", 0], ["me", 1]]), trie), true)
90
+ *
91
+ * @since 2.0.0
92
+ * @category constructors
93
+ */
94
+ export const make: <Entries extends Array<readonly [string, any]>>(
95
+ ...entries: Entries
96
+ ) => Trie<Entries[number] extends readonly [any, infer V] ? V : never> = TR.make
97
+
98
+ /**
99
+ * Insert a new entry in the `Trie`.
100
+ *
101
+ * @example
102
+ * import * as Trie from "effect/Trie"
103
+ *
104
+ * const trie1 = Trie.empty<number>().pipe(
105
+ * Trie.insert("call", 0)
106
+ * )
107
+ * const trie2 = trie1.pipe(Trie.insert("me", 1))
108
+ * const trie3 = trie2.pipe(Trie.insert("mind", 2))
109
+ * const trie4 = trie3.pipe(Trie.insert("mid", 3))
110
+ *
111
+ * assert.deepStrictEqual(Array.from(trie1), [["call", 0]])
112
+ * assert.deepStrictEqual(Array.from(trie2), [["call", 0], ["me", 1]])
113
+ * assert.deepStrictEqual(Array.from(trie3), [["call", 0], ["me", 1], ["mind", 2]])
114
+ * assert.deepStrictEqual(Array.from(trie4), [["call", 0], ["me", 1], ["mid", 3], ["mind", 2]])
115
+ *
116
+ * @since 2.0.0
117
+ * @category mutations
118
+ */
119
+ export const insert: {
120
+ <V>(key: string, value: V): (self: Trie<V>) => Trie<V>
121
+ <V>(self: Trie<V>, key: string, value: V): Trie<V>
122
+ } = TR.insert
123
+
124
+ /**
125
+ * Returns an `IterableIterator` of the keys within the `Trie`.
126
+ *
127
+ * The keys are returned in alphabetical order, regardless of insertion order.
128
+ *
129
+ * @example
130
+ * import * as Trie from "effect/Trie"
131
+ *
132
+ * const trie = Trie.empty<number>().pipe(
133
+ * Trie.insert("cab", 0),
134
+ * Trie.insert("abc", 1),
135
+ * Trie.insert("bca", 2)
136
+ * )
137
+ *
138
+ * const result = Array.from(Trie.keys(trie))
139
+ * assert.deepStrictEqual(result, ["abc", "bca", "cab"])
140
+ *
141
+ * @since 2.0.0
142
+ * @category getters
143
+ */
144
+ export const keys: <V>(self: Trie<V>) => IterableIterator<string> = TR.keys
145
+
146
+ /**
147
+ * Returns an `IterableIterator` of the values within the `Trie`.
148
+ *
149
+ * Values are ordered based on their key in alphabetical order, regardless of insertion order.
150
+ *
151
+ * @example
152
+ * import * as Trie from "effect/Trie"
153
+ *
154
+ * const trie = Trie.empty<number>().pipe(
155
+ * Trie.insert("call", 0),
156
+ * Trie.insert("me", 1),
157
+ * Trie.insert("and", 2)
158
+ * )
159
+ *
160
+ * const result = Array.from(Trie.values(trie))
161
+ * assert.deepStrictEqual(result, [2, 0, 1])
162
+ *
163
+ * @since 2.0.0
164
+ * @category getters
165
+ */
166
+ export const values: <V>(self: Trie<V>) => IterableIterator<V> = TR.values
167
+
168
+ /**
169
+ * Returns an `IterableIterator` of the entries within the `Trie`.
170
+ *
171
+ * The entries are returned by keys in alphabetical order, regardless of insertion order.
172
+ *
173
+ * @example
174
+ * import * as Trie from "effect/Trie"
175
+ *
176
+ * const trie = Trie.empty<number>().pipe(
177
+ * Trie.insert("call", 0),
178
+ * Trie.insert("me", 1)
179
+ * )
180
+ *
181
+ * const result = Array.from(Trie.entries(trie))
182
+ * assert.deepStrictEqual(result, [["call", 0], ["me", 1]])
183
+ *
184
+ * @since 2.0.0
185
+ * @category getters
186
+ */
187
+ export const entries: <V>(self: Trie<V>) => IterableIterator<[string, V]> = TR.entries
188
+
189
+ /**
190
+ * Returns an `Array<[K, V]>` of the entries within the `Trie`.
191
+ *
192
+ * Equivalent to `Array.from(Trie.entries(trie))`.
193
+ *
194
+ * @example
195
+ * import * as Trie from "effect/Trie"
196
+ *
197
+ * const trie = Trie.empty<number>().pipe(
198
+ * Trie.insert("call", 0),
199
+ * Trie.insert("me", 1)
200
+ * )
201
+ * const result = Trie.toEntries(trie)
202
+ *
203
+ * assert.deepStrictEqual(result, [["call", 0], ["me", 1]])
204
+ *
205
+ * @since 2.0.0
206
+ * @category getters
207
+ */
208
+ export const toEntries = <V>(self: Trie<V>): Array<[string, V]> => Array.from(entries(self))
209
+
210
+ /**
211
+ * Returns an `IterableIterator` of the keys within the `Trie`
212
+ * that have `prefix` as prefix (`prefix` included if it exists).
213
+ *
214
+ * @example
215
+ * import * as Trie from "effect/Trie"
216
+ *
217
+ * const trie = Trie.empty<number>().pipe(
218
+ * Trie.insert("she", 0),
219
+ * Trie.insert("shells", 1),
220
+ * Trie.insert("sea", 2),
221
+ * Trie.insert("shore", 3)
222
+ * )
223
+ *
224
+ * const result = Array.from(Trie.keysWithPrefix(trie, "she"))
225
+ * assert.deepStrictEqual(result, ["she", "shells"])
226
+ *
227
+ * @since 2.0.0
228
+ * @category getters
229
+ */
230
+ export const keysWithPrefix: {
231
+ (prefix: string): <V>(self: Trie<V>) => IterableIterator<string>
232
+ <V>(self: Trie<V>, prefix: string): IterableIterator<string>
233
+ } = TR.keysWithPrefix
234
+
235
+ /**
236
+ * Returns an `IterableIterator` of the values within the `Trie`
237
+ * that have `prefix` as prefix (`prefix` included if it exists).
238
+ *
239
+ * @example
240
+ * import * as Trie from "effect/Trie"
241
+ *
242
+ * const trie = Trie.empty<number>().pipe(
243
+ * Trie.insert("she", 0),
244
+ * Trie.insert("shells", 1),
245
+ * Trie.insert("sea", 2),
246
+ * Trie.insert("shore", 3)
247
+ * )
248
+ *
249
+ * const result = Array.from(Trie.valuesWithPrefix(trie, "she"))
250
+ *
251
+ * // 0: "she", 1: "shells"
252
+ * assert.deepStrictEqual(result, [0, 1])
253
+ *
254
+ * @since 2.0.0
255
+ * @category getters
256
+ */
257
+ export const valuesWithPrefix: {
258
+ (prefix: string): <V>(self: Trie<V>) => IterableIterator<V>
259
+ <V>(self: Trie<V>, prefix: string): IterableIterator<V>
260
+ } = TR.valuesWithPrefix
261
+
262
+ /**
263
+ * Returns an `IterableIterator` of the entries within the `Trie`
264
+ * that have `prefix` as prefix (`prefix` included if it exists).
265
+ *
266
+ * @example
267
+ * import * as Trie from "effect/Trie"
268
+ *
269
+ * const trie = Trie.empty<number>().pipe(
270
+ * Trie.insert("she", 0),
271
+ * Trie.insert("shells", 1),
272
+ * Trie.insert("sea", 2),
273
+ * Trie.insert("shore", 3)
274
+ * )
275
+ *
276
+ * const result = Array.from(Trie.entriesWithPrefix(trie, "she"))
277
+ * assert.deepStrictEqual(result, [["she", 0], ["shells", 1]])
278
+ *
279
+ * @since 2.0.0
280
+ * @category getters
281
+ */
282
+ export const entriesWithPrefix: {
283
+ (prefix: string): <V>(self: Trie<V>) => IterableIterator<[string, V]>
284
+ <V>(self: Trie<V>, prefix: string): IterableIterator<[string, V]>
285
+ } = TR.entriesWithPrefix
286
+
287
+ /**
288
+ * Returns `Array<[K, V]>` of the entries within the `Trie`
289
+ * that have `prefix` as prefix (`prefix` included if it exists).
290
+ *
291
+ * @example
292
+ * import * as Trie from "effect/Trie"
293
+ *
294
+ * const trie = Trie.empty<number>().pipe(
295
+ * Trie.insert("shells", 0),
296
+ * Trie.insert("sells", 1),
297
+ * Trie.insert("sea", 2),
298
+ * Trie.insert("she", 3)
299
+ * )
300
+ *
301
+ * const result = Trie.toEntriesWithPrefix(trie, "she")
302
+ * assert.deepStrictEqual(result, [["she", 3], ["shells", 0]])
303
+ *
304
+ * @since 2.0.0
305
+ * @category getters
306
+ */
307
+ export const toEntriesWithPrefix: {
308
+ (prefix: string): <V>(self: Trie<V>) => Array<[string, V]>
309
+ <V>(self: Trie<V>, prefix: string): Array<[string, V]>
310
+ } = TR.toEntriesWithPrefix
311
+
312
+ /**
313
+ * Returns the longest key/value in the `Trie`
314
+ * that is a prefix of that `key` if it exists, `None` otherwise.
315
+ *
316
+ * @example
317
+ * import * as Trie from "effect/Trie"
318
+ * import * as Option from "effect/Option"
319
+ *
320
+ * const trie = Trie.empty<number>().pipe(
321
+ * Trie.insert("shells", 0),
322
+ * Trie.insert("sells", 1),
323
+ * Trie.insert("she", 2)
324
+ * )
325
+ *
326
+ * assert.deepStrictEqual(Trie.longestPrefixOf(trie, "sell"), Option.none())
327
+ * assert.deepStrictEqual(Trie.longestPrefixOf(trie, "sells"), Option.some(["sells", 1]))
328
+ * assert.deepStrictEqual(Trie.longestPrefixOf(trie, "shell"), Option.some(["she", 2]))
329
+ * assert.deepStrictEqual(Trie.longestPrefixOf(trie, "shellsort"), Option.some(["shells", 0]))
330
+ *
331
+ * @since 2.0.0
332
+ * @category getters
333
+ */
334
+ export const longestPrefixOf: {
335
+ (key: string): <V>(self: Trie<V>) => Option<[string, V]>
336
+ <V>(self: Trie<V>, key: string): Option<[string, V]>
337
+ } = TR.longestPrefixOf
338
+
339
+ /**
340
+ * Returns the size of the `Trie` (number of entries in the `Trie`).
341
+ *
342
+ * @example
343
+ * import * as Trie from "effect/Trie"
344
+ *
345
+ * const trie = Trie.empty<number>().pipe(
346
+ * Trie.insert("a", 0),
347
+ * Trie.insert("b", 1)
348
+ * )
349
+ *
350
+ * assert.equal(Trie.size(trie), 2)
351
+ *
352
+ * @since 2.0.0
353
+ * @category getters
354
+ */
355
+ export const size: <V>(self: Trie<V>) => number = TR.size
356
+
357
+ /**
358
+ * Safely lookup the value for the specified key in the `Trie`.
359
+ *
360
+ * @example
361
+ * import * as Trie from "effect/Trie"
362
+ * import * as Option from "effect/Option"
363
+ *
364
+ * const trie = Trie.empty<number>().pipe(
365
+ * Trie.insert("call", 0),
366
+ * Trie.insert("me", 1),
367
+ * Trie.insert("mind", 2),
368
+ * Trie.insert("mid", 3)
369
+ * )
370
+ *
371
+ * assert.deepStrictEqual(Trie.get(trie, "call"), Option.some(0))
372
+ * assert.deepStrictEqual(Trie.get(trie, "me"), Option.some(1))
373
+ * assert.deepStrictEqual(Trie.get(trie, "mind"), Option.some(2))
374
+ * assert.deepStrictEqual(Trie.get(trie, "mid"), Option.some(3))
375
+ * assert.deepStrictEqual(Trie.get(trie, "cale"), Option.none())
376
+ * assert.deepStrictEqual(Trie.get(trie, "ma"), Option.none())
377
+ * assert.deepStrictEqual(Trie.get(trie, "midn"), Option.none())
378
+ * assert.deepStrictEqual(Trie.get(trie, "mea"), Option.none())
379
+ *
380
+ * @since 2.0.0
381
+ * @category elements
382
+ */
383
+ export const get: {
384
+ (key: string): <V>(self: Trie<V>) => Option<V>
385
+ <V>(self: Trie<V>, key: string): Option<V>
386
+ } = TR.get
387
+
388
+ /**
389
+ * Check if the given key exists in the `Trie`.
390
+ *
391
+ * @example
392
+ * import * as Trie from "effect/Trie"
393
+ *
394
+ * const trie = Trie.empty<number>().pipe(
395
+ * Trie.insert("call", 0),
396
+ * Trie.insert("me", 1),
397
+ * Trie.insert("mind", 2),
398
+ * Trie.insert("mid", 3)
399
+ * )
400
+ *
401
+ * assert.equal(Trie.has(trie, "call"), true)
402
+ * assert.equal(Trie.has(trie, "me"), true)
403
+ * assert.equal(Trie.has(trie, "mind"), true)
404
+ * assert.equal(Trie.has(trie, "mid"), true)
405
+ * assert.equal(Trie.has(trie, "cale"), false)
406
+ * assert.equal(Trie.has(trie, "ma"), false)
407
+ * assert.equal(Trie.has(trie, "midn"), false)
408
+ * assert.equal(Trie.has(trie, "mea"), false)
409
+ *
410
+ * @since 2.0.0
411
+ * @category elements
412
+ */
413
+ export const has: {
414
+ (key: string): <V>(self: Trie<V>) => boolean
415
+ <V>(self: Trie<V>, key: string): boolean
416
+ } = TR.has
417
+
418
+ /**
419
+ * Checks if the `Trie` contains any entries.
420
+ *
421
+ * @example
422
+ * import * as Trie from "effect/Trie"
423
+ *
424
+ * const trie = Trie.empty<number>()
425
+ * const trie1 = trie.pipe(Trie.insert("ma", 0))
426
+ *
427
+ * assert.equal(Trie.isEmpty(trie), true)
428
+ * assert.equal(Trie.isEmpty(trie1), false)
429
+ *
430
+ * @since 2.0.0
431
+ * @category elements
432
+ */
433
+ export const isEmpty: <V>(self: Trie<V>) => boolean = TR.isEmpty
434
+
435
+ /**
436
+ * Unsafely lookup the value for the specified key in the `Trie`.
437
+ *
438
+ * `unsafeGet` will throw if the key is not found. Use `get` instead to safely
439
+ * get a value from the `Trie`.
440
+ *
441
+ * @example
442
+ * import * as Trie from "effect/Trie"
443
+ *
444
+ * const trie = Trie.empty<number>().pipe(
445
+ * Trie.insert("call", 0),
446
+ * Trie.insert("me", 1)
447
+ * )
448
+ *
449
+ * assert.throws(() => Trie.unsafeGet(trie, "mae"))
450
+ *
451
+ * @since 2.0.0
452
+ * @category unsafe
453
+ */
454
+ export const unsafeGet: {
455
+ (key: string): <V>(self: Trie<V>) => V
456
+ <V>(self: Trie<V>, key: string): V
457
+ } = TR.unsafeGet
458
+
459
+ /**
460
+ * Remove the entry for the specified key in the `Trie`.
461
+ *
462
+ * @example
463
+ * import * as Trie from "effect/Trie"
464
+ * import * as Option from "effect/Option"
465
+ *
466
+ * const trie = Trie.empty<number>().pipe(
467
+ * Trie.insert("call", 0),
468
+ * Trie.insert("me", 1),
469
+ * Trie.insert("mind", 2),
470
+ * Trie.insert("mid", 3)
471
+ * )
472
+ *
473
+ * const trie1 = trie.pipe(Trie.remove("call"))
474
+ * const trie2 = trie1.pipe(Trie.remove("mea"))
475
+ *
476
+ * assert.deepStrictEqual(Trie.get(trie, "call"), Option.some(0))
477
+ * assert.deepStrictEqual(Trie.get(trie1, "call"), Option.none())
478
+ * assert.deepStrictEqual(Trie.get(trie2, "call"), Option.none())
479
+ *
480
+ * @since 2.0.0
481
+ * @category mutations
482
+ */
483
+ export const remove: {
484
+ (key: string): <V>(self: Trie<V>) => Trie<V>
485
+ <V>(self: Trie<V>, key: string): Trie<V>
486
+ } = TR.remove
487
+
488
+ /**
489
+ * Reduce a state over the entries of the `Trie`.
490
+ *
491
+ * @example
492
+ * import * as Trie from "effect/Trie"
493
+ *
494
+ * const trie = Trie.empty<number>().pipe(
495
+ * Trie.insert("shells", 0),
496
+ * Trie.insert("sells", 1),
497
+ * Trie.insert("she", 2)
498
+ * )
499
+ *
500
+ * assert.equal(
501
+ * trie.pipe(
502
+ * Trie.reduce(0, (acc, n) => acc + n)
503
+ * ),
504
+ * 3
505
+ * )
506
+ * assert.equal(
507
+ * trie.pipe(
508
+ * Trie.reduce(10, (acc, n) => acc + n)
509
+ * ),
510
+ * 13
511
+ * )
512
+ * assert.equal(
513
+ * trie.pipe(
514
+ * Trie.reduce("", (acc, _, key) => acc + key)
515
+ * ),
516
+ * "sellssheshells"
517
+ * )
518
+ *
519
+ * @since 2.0.0
520
+ * @category folding
521
+ */
522
+ export const reduce: {
523
+ <Z, V>(zero: Z, f: (accumulator: Z, value: V, key: string) => Z): (self: Trie<V>) => Z
524
+ <Z, V>(self: Trie<V>, zero: Z, f: (accumulator: Z, value: V, key: string) => Z): Z
525
+ } = TR.reduce
526
+
527
+ /**
528
+ * Maps over the entries of the `Trie` using the specified function.
529
+ *
530
+ * @example
531
+ * import * as Trie from "effect/Trie"
532
+ * import * as Equal from "effect/Equal"
533
+ *
534
+ * const trie = Trie.empty<number>().pipe(
535
+ * Trie.insert("shells", 0),
536
+ * Trie.insert("sells", 1),
537
+ * Trie.insert("she", 2)
538
+ * )
539
+ *
540
+ * const trieMapV = Trie.empty<number>().pipe(
541
+ * Trie.insert("shells", 1),
542
+ * Trie.insert("sells", 2),
543
+ * Trie.insert("she", 3)
544
+ * )
545
+ *
546
+ * const trieMapK = Trie.empty<number>().pipe(
547
+ * Trie.insert("shells", 6),
548
+ * Trie.insert("sells", 5),
549
+ * Trie.insert("she", 3)
550
+ * )
551
+ *
552
+ * assert.equal(Equal.equals(Trie.map(trie, (v) => v + 1), trieMapV), true)
553
+ * assert.equal(Equal.equals(Trie.map(trie, (_, k) => k.length), trieMapK), true)
554
+ *
555
+ * @since 2.0.0
556
+ * @category folding
557
+ */
558
+ export const map: {
559
+ <A, V>(f: (value: V, key: string) => A): (self: Trie<V>) => Trie<A>
560
+ <V, A>(self: Trie<V>, f: (value: V, key: string) => A): Trie<A>
561
+ } = TR.map
562
+
563
+ /**
564
+ * Filters entries out of a `Trie` using the specified predicate.
565
+ *
566
+ * @example
567
+ * import * as Trie from "effect/Trie"
568
+ * import * as Equal from "effect/Equal"
569
+ *
570
+ * const trie = Trie.empty<number>().pipe(
571
+ * Trie.insert("shells", 0),
572
+ * Trie.insert("sells", 1),
573
+ * Trie.insert("she", 2)
574
+ * )
575
+ *
576
+ * const trieMapV = Trie.empty<number>().pipe(
577
+ * Trie.insert("she", 2)
578
+ * )
579
+ *
580
+ * const trieMapK = Trie.empty<number>().pipe(
581
+ * Trie.insert("shells", 0),
582
+ * Trie.insert("sells", 1)
583
+ * )
584
+ *
585
+ * assert.equal(Equal.equals(Trie.filter(trie, (v) => v > 1), trieMapV), true)
586
+ * assert.equal(Equal.equals(Trie.filter(trie, (_, k) => k.length > 3), trieMapK), true)
587
+ *
588
+ * @since 2.0.0
589
+ * @category filtering
590
+ */
591
+ export const filter: {
592
+ <A, B extends A>(f: (a: A, k: string) => a is B): (self: Trie<A>) => Trie<B>
593
+ <B extends A, A = B>(f: (a: A, k: string) => boolean): (self: Trie<B>) => Trie<B>
594
+ <A, B extends A>(self: Trie<A>, f: (a: A, k: string) => a is B): Trie<B>
595
+ <A>(self: Trie<A>, f: (a: A, k: string) => boolean): Trie<A>
596
+ } = TR.filter
597
+
598
+ /**
599
+ * Maps over the entries of the `Trie` using the specified partial function
600
+ * and filters out `None` values.
601
+ *
602
+ * @example
603
+ * import * as Trie from "effect/Trie"
604
+ * import * as Equal from "effect/Equal"
605
+ * import * as Option from "effect/Option"
606
+ *
607
+ * const trie = Trie.empty<number>().pipe(
608
+ * Trie.insert("shells", 0),
609
+ * Trie.insert("sells", 1),
610
+ * Trie.insert("she", 2)
611
+ * )
612
+ *
613
+ * const trieMapV = Trie.empty<number>().pipe(
614
+ * Trie.insert("she", 2)
615
+ * )
616
+ *
617
+ * const trieMapK = Trie.empty<number>().pipe(
618
+ * Trie.insert("shells", 0),
619
+ * Trie.insert("sells", 1)
620
+ * )
621
+ *
622
+ * assert.equal(Equal.equals(Trie.filterMap(trie, (v) => v > 1 ? Option.some(v) : Option.none()), trieMapV), true)
623
+ * assert.equal(
624
+ * Equal.equals(Trie.filterMap(trie, (v, k) => k.length > 3 ? Option.some(v) : Option.none()), trieMapK),
625
+ * true
626
+ * )
627
+ *
628
+ * @since 2.0.0
629
+ * @category filtering
630
+ */
631
+ export const filterMap: {
632
+ <A, B>(f: (value: A, key: string) => Option<B>): (self: Trie<A>) => Trie<B>
633
+ <A, B>(self: Trie<A>, f: (value: A, key: string) => Option<B>): Trie<B>
634
+ } = TR.filterMap
635
+
636
+ /**
637
+ * Filters out `None` values from a `Trie` of `Options`s.
638
+ *
639
+ * @example
640
+ * import * as Trie from "effect/Trie"
641
+ * import * as Equal from "effect/Equal"
642
+ * import * as Option from "effect/Option"
643
+ *
644
+ * const trie = Trie.empty<Option.Option<number>>().pipe(
645
+ * Trie.insert("shells", Option.some(0)),
646
+ * Trie.insert("sells", Option.none()),
647
+ * Trie.insert("she", Option.some(2))
648
+ * )
649
+ *
650
+ * const trieMapV = Trie.empty<number>().pipe(
651
+ * Trie.insert("shells", 0),
652
+ * Trie.insert("she", 2)
653
+ * )
654
+ *
655
+ * assert.equal(Equal.equals(Trie.compact(trie), trieMapV), true)
656
+ *
657
+ * @since 2.0.0
658
+ * @category filtering
659
+ */
660
+ export const compact: <A>(self: Trie<Option<A>>) => Trie<A> = TR.compact
661
+
662
+ /**
663
+ * Applies the specified function to the entries of the `Trie`.
664
+ *
665
+ * @example
666
+ * import * as Trie from "effect/Trie"
667
+ *
668
+ * let value = 0
669
+ *
670
+ * Trie.empty<number>().pipe(
671
+ * Trie.insert("shells", 0),
672
+ * Trie.insert("sells", 1),
673
+ * Trie.insert("she", 2),
674
+ * Trie.forEach((n, key) => {
675
+ * value += n + key.length
676
+ * })
677
+ * )
678
+ *
679
+ * assert.equal(value, 17)
680
+ *
681
+ * @since 2.0.0
682
+ * @category traversing
683
+ */
684
+ export const forEach: {
685
+ <V>(f: (value: V, key: string) => void): (self: Trie<V>) => void
686
+ <V>(self: Trie<V>, f: (value: V, key: string) => void): void
687
+ } = TR.forEach
688
+
689
+ /**
690
+ * Updates the value of the specified key within the `Trie` if it exists.
691
+ *
692
+ * @example
693
+ * import * as Trie from "effect/Trie"
694
+ * import * as Equal from "effect/Equal"
695
+ * import * as Option from "effect/Option"
696
+ *
697
+ * const trie = Trie.empty<number>().pipe(
698
+ * Trie.insert("shells", 0),
699
+ * Trie.insert("sells", 1),
700
+ * Trie.insert("she", 2)
701
+ * )
702
+ *
703
+ * assert.deepStrictEqual(trie.pipe(Trie.modify("she", (v) => v + 10), Trie.get("she")), Option.some(12))
704
+ *
705
+ * assert.equal(Equal.equals(trie.pipe(Trie.modify("me", (v) => v)), trie), true)
706
+ *
707
+ * @since 2.0.0
708
+ * @category mutations
709
+ */
710
+ export const modify: {
711
+ <V>(key: string, f: (v: V) => V): (self: Trie<V>) => Trie<V>
712
+ <V>(self: Trie<V>, key: string, f: (v: V) => V): Trie<V>
713
+ } = TR.modify
714
+
715
+ /**
716
+ * Removes all entries in the `Trie` which have the specified keys.
717
+ *
718
+ * @example
719
+ * import * as Trie from "effect/Trie"
720
+ * import * as Equal from "effect/Equal"
721
+ *
722
+ * const trie = Trie.empty<number>().pipe(
723
+ * Trie.insert("shells", 0),
724
+ * Trie.insert("sells", 1),
725
+ * Trie.insert("she", 2)
726
+ * )
727
+ *
728
+ * assert.equal(
729
+ * Equal.equals(trie.pipe(Trie.removeMany(["she", "sells"])), Trie.empty<number>().pipe(Trie.insert("shells", 0))),
730
+ * true
731
+ * )
732
+ *
733
+ * @since 2.0.0
734
+ * @category mutations
735
+ */
736
+ export const removeMany: {
737
+ (keys: Iterable<string>): <V>(self: Trie<V>) => Trie<V>
738
+ <V>(self: Trie<V>, keys: Iterable<string>): Trie<V>
739
+ } = TR.removeMany
740
+
741
+ /**
742
+ * Insert multiple entries in the `Trie` at once.
743
+ *
744
+ * @example
745
+ * import * as Trie from "effect/Trie"
746
+ * import * as Equal from "effect/Equal"
747
+ *
748
+ * const trie = Trie.empty<number>().pipe(
749
+ * Trie.insert("shells", 0),
750
+ * Trie.insert("sells", 1),
751
+ * Trie.insert("she", 2)
752
+ * )
753
+ *
754
+ * const trieInsert = Trie.empty<number>().pipe(
755
+ * Trie.insert("shells", 0),
756
+ * Trie.insertMany(
757
+ * [["sells", 1], ["she", 2]]
758
+ * )
759
+ * )
760
+ *
761
+ * assert.equal(
762
+ * Equal.equals(trie, trieInsert),
763
+ * true
764
+ * )
765
+ *
766
+ * @since 2.0.0
767
+ * @category mutations
768
+ */
769
+ export const insertMany: {
770
+ <V>(iter: Iterable<[string, V]>): (self: Trie<V>) => Trie<V>
771
+ <V>(self: Trie<V>, iter: Iterable<[string, V]>): Trie<V>
772
+ } = TR.insertMany