effect 2.0.3 → 2.0.5
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/FiberMap/package.json +6 -0
- package/FiberSet/package.json +6 -0
- package/Trie/package.json +6 -0
- package/dist/cjs/FiberMap.js +190 -0
- package/dist/cjs/FiberMap.js.map +1 -0
- package/dist/cjs/FiberSet.js +150 -0
- package/dist/cjs/FiberSet.js.map +1 -0
- package/dist/cjs/MutableHashMap.js +11 -1
- package/dist/cjs/MutableHashMap.js.map +1 -1
- package/dist/cjs/MutableHashSet.js +7 -1
- package/dist/cjs/MutableHashSet.js.map +1 -1
- package/dist/cjs/MutableList.js +8 -11
- package/dist/cjs/MutableList.js.map +1 -1
- package/dist/cjs/Schedule.js.map +1 -1
- package/dist/cjs/Struct.js +16 -1
- package/dist/cjs/Struct.js.map +1 -1
- package/dist/cjs/Trie.js +680 -0
- package/dist/cjs/Trie.js.map +1 -0
- package/dist/cjs/index.js +8 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/internal/hashMap/node.js +2 -2
- package/dist/cjs/internal/hashMap/node.js.map +1 -1
- package/dist/cjs/internal/pubsub.js +11 -17
- package/dist/cjs/internal/pubsub.js.map +1 -1
- package/dist/cjs/internal/redBlackTree/node.js +35 -30
- package/dist/cjs/internal/redBlackTree/node.js.map +1 -1
- package/dist/cjs/internal/redBlackTree.js +69 -13
- package/dist/cjs/internal/redBlackTree.js.map +1 -1
- package/dist/cjs/internal/schedule.js +1 -1
- package/dist/cjs/internal/schedule.js.map +1 -1
- package/dist/cjs/internal/stack.js +6 -11
- package/dist/cjs/internal/stack.js.map +1 -1
- package/dist/cjs/internal/trie.js +588 -0
- package/dist/cjs/internal/trie.js.map +1 -0
- package/dist/cjs/internal/version.js +1 -1
- package/dist/dts/FiberMap.d.ts +135 -0
- package/dist/dts/FiberMap.d.ts.map +1 -0
- package/dist/dts/FiberSet.d.ts +99 -0
- package/dist/dts/FiberSet.d.ts.map +1 -0
- package/dist/dts/MutableHashMap.d.ts +4 -0
- package/dist/dts/MutableHashMap.d.ts.map +1 -1
- package/dist/dts/MutableHashSet.d.ts +5 -0
- package/dist/dts/MutableHashSet.d.ts.map +1 -1
- package/dist/dts/MutableList.d.ts.map +1 -1
- package/dist/dts/Schedule.d.ts +2 -1
- package/dist/dts/Schedule.d.ts.map +1 -1
- package/dist/dts/Struct.d.ts +17 -3
- package/dist/dts/Struct.d.ts.map +1 -1
- package/dist/dts/Trie.d.ts +740 -0
- package/dist/dts/Trie.d.ts.map +1 -0
- package/dist/dts/Types.d.ts +4 -0
- package/dist/dts/Types.d.ts.map +1 -1
- package/dist/dts/index.d.ts +26 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/redBlackTree/node.d.ts +8 -0
- package/dist/dts/internal/redBlackTree/node.d.ts.map +1 -1
- package/dist/dts/internal/stack.d.ts +1 -1
- package/dist/dts/internal/stack.d.ts.map +1 -1
- package/dist/dts/internal/trie.d.ts +2 -0
- package/dist/dts/internal/trie.d.ts.map +1 -0
- package/dist/dts/internal/version.d.ts +1 -1
- package/dist/esm/FiberMap.js +154 -0
- package/dist/esm/FiberMap.js.map +1 -0
- package/dist/esm/FiberSet.js +114 -0
- package/dist/esm/FiberSet.js.map +1 -0
- package/dist/esm/MutableHashMap.js +9 -0
- package/dist/esm/MutableHashMap.js.map +1 -1
- package/dist/esm/MutableHashSet.js +5 -0
- package/dist/esm/MutableHashSet.js.map +1 -1
- package/dist/esm/MutableList.js +8 -11
- package/dist/esm/MutableList.js.map +1 -1
- package/dist/esm/Schedule.js.map +1 -1
- package/dist/esm/Struct.js +14 -0
- package/dist/esm/Struct.js.map +1 -1
- package/dist/esm/Trie.js +648 -0
- package/dist/esm/Trie.js.map +1 -0
- package/dist/esm/index.js +26 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/hashMap/node.js +2 -2
- package/dist/esm/internal/hashMap/node.js.map +1 -1
- package/dist/esm/internal/pubsub.js +11 -17
- package/dist/esm/internal/pubsub.js.map +1 -1
- package/dist/esm/internal/redBlackTree/node.js +31 -25
- package/dist/esm/internal/redBlackTree/node.js.map +1 -1
- package/dist/esm/internal/redBlackTree.js +69 -13
- package/dist/esm/internal/redBlackTree.js.map +1 -1
- package/dist/esm/internal/schedule.js +1 -1
- package/dist/esm/internal/schedule.js.map +1 -1
- package/dist/esm/internal/stack.js +4 -9
- package/dist/esm/internal/stack.js.map +1 -1
- package/dist/esm/internal/trie.js +547 -0
- package/dist/esm/internal/trie.js.map +1 -0
- package/dist/esm/internal/version.js +1 -1
- package/package.json +25 -1
- package/src/FiberMap.ts +296 -0
- package/src/FiberSet.ts +194 -0
- package/src/MutableHashMap.ts +10 -0
- package/src/MutableHashSet.ts +6 -0
- package/src/MutableList.ts +15 -7
- package/src/Schedule.ts +2 -1
- package/src/Struct.ts +24 -6
- package/src/Trie.ts +772 -0
- package/src/Types.ts +5 -0
- package/src/index.ts +29 -0
- package/src/internal/hashMap/node.ts +3 -3
- package/src/internal/pubsub.ts +15 -14
- package/src/internal/redBlackTree/node.ts +37 -17
- package/src/internal/redBlackTree.ts +73 -38
- package/src/internal/schedule.ts +2 -2
- package/src/internal/stack.ts +8 -2
- package/src/internal/trie.ts +721 -0
- 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
|