functionalscript 0.0.291 → 0.0.295

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/README.md CHANGED
@@ -203,17 +203,6 @@ x[0] = 3 // < invalid
203
203
  const f = () => x // < invalid
204
204
  ```
205
205
 
206
-
207
-
208
- This mutable object cannot be used in [closures](https://en.wikipedia.org/wiki/Closure_(computer_programming)) or nested functions.
209
-
210
- An example of incorrect code would look like this:
211
-
212
- ```js
213
- let x = 5
214
- const f = () => x
215
- ```
216
-
217
206
  ### 5.2 Return
218
207
 
219
208
  [Return](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.291",
3
+ "version": "0.0.295",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -28,7 +28,7 @@
28
28
  },
29
29
  "homepage": "https://github.com/functionalscript/functionalscript#readme",
30
30
  "devDependencies": {
31
- "@types/node": "^16.11.12",
32
- "typescript": "^4.5.3"
31
+ "@types/node": "^16.11.19",
32
+ "typescript": "^4.5.4"
33
33
  }
34
34
  }
@@ -79,14 +79,16 @@ Posible actions:
79
79
 
80
80
  ## Concat
81
81
 
82
- `concat` returns either `Branch1` or `Branch3`
83
-
84
- |`a` |`b` | |size |
85
- |------------------|-------------------|-------------------------------------------------|-----|
86
- |`[av]` |`[bv]` |`[[av,bv]]` | |
87
- | |`[bv0,bv1]` |`[a,bv0,[bv1]]` | |
88
- |`[av0,av1]` | |`[[av0],av1,b]` | |
89
- |`[...aHead,aLast]`|`[bFirst,...bLast]`|`up([...aHead,...concat(aLast,bFirst),...bTail])`|5..11|
82
+ `concat` accepts `left` and `right` branches of the same level.
83
+
84
+ |left |right |result |
85
+ |-------------|-------------|--------------------------|
86
+ |[an0] |[bn0] |[an0, value, r?] |
87
+ |[an0] |[bn0,bv1,bn2]|[an0, value, r?, bv1, bn2]|
88
+ |[an0,av1,an2]|[bn0] |[an0, av1, an2, value, r?]|
89
+
90
+ `popLeft` accepts `node` and returns
91
+ `value` and `['leaf', [] | Leaf1]` | `['branch', Branch1 | Branch3 | Branch5]`
90
92
 
91
93
  ## Up
92
94
 
@@ -98,7 +98,29 @@ const find = c => {
98
98
  return f(undefined)
99
99
  }
100
100
 
101
+ /** @type {<T>(first: First<T>) => T | undefined} */
102
+ const value = first => {
103
+ switch (first[0]) {
104
+ case 1: {
105
+ const x = first[1]
106
+ switch (x.length) {
107
+ case 1: case 2: { return x[0] }
108
+ default: { return x[1] }
109
+ }
110
+ }
111
+ case 3: {
112
+ const x = first[1]
113
+ return x.length === 2 ? x[1] : x[3]
114
+ }
115
+ default: {
116
+ return undefined
117
+ }
118
+ }
119
+ }
120
+
101
121
  module.exports = {
102
122
  /** @readonly */
103
123
  find,
124
+ /** @readonly */
125
+ value,
104
126
  }
@@ -4,17 +4,12 @@ const json = require('../../../json')
4
4
  const { sort } = require('../../object')
5
5
  const btree = require('..')
6
6
  const { stringCmp } = require('../../function/compare')
7
+ const s = require('../set')
7
8
 
8
9
  const jsonStr = json.stringify(sort)
9
10
 
10
11
  /** @type {(node: btree.Node<string>) => (value: string) => btree.Node<string>} */
11
- const set = node => value => {
12
- const result = btree.setVisitor(stringCmp(value))(node)(() => value)
13
- switch (result[0]) {
14
- case 'replace': case 'overflow': { return result[1] }
15
- default: { return node }
16
- }
17
- }
12
+ const set = node => value => s.set(stringCmp(value))(value)(node)
18
13
 
19
14
  /** @type {(r: _.Result<json.Unknown>) => string} */
20
15
  const str = r => jsonStr(list.toArray(list.map(x => x[0])(r)))
@@ -1,18 +1,5 @@
1
- const { todo } = require('../../dev')
2
- const cmp = require('../function/compare')
3
- const { index3, index5 } = cmp
4
1
  const seq = require('../list')
5
2
 
6
- /**
7
- * @template T
8
- * @typedef {() => T} Lazy
9
- */
10
-
11
- /**
12
- * @template T
13
- * @typedef {cmp.Compare<T>} Cmp
14
- */
15
-
16
3
  /**
17
4
  * @template T
18
5
  * @typedef {readonly[T]} Array1
@@ -61,268 +48,11 @@ const seq = require('../list')
61
48
  * @typedef { Leaf1<T> | Leaf2<T> | Branch3<T> | Branch5<T>} Node
62
49
  */
63
50
 
64
- /** @typedef {readonly['done']} NotFoundDone */
65
-
66
- /**
67
- * @template T
68
- * @typedef {readonly['done', T]} FoundDone
69
- */
70
-
71
- /**
72
- * @template T
73
- * @typedef { NotFoundDone | FoundDone<T> } Done
74
- */
75
-
76
- /**
77
- * @template T
78
- * @typedef {readonly['replace', Node<T>]} Replace
79
- */
80
-
81
- /**
82
- * @template T
83
- * @typedef {readonly['overflow', Branch3<T>]} Overflow
84
- */
85
-
86
- /**
87
- * @template T
88
- * @typedef { Done<T> | Replace<T> | Overflow<T> } Result
89
- */
90
-
91
- /** @typedef {<T>(_: Leaf1<T>) => LazyResult<T>} InLeaf1 */
92
- /** @typedef {<T>(_: Leaf2<T>) => LazyResult<T>} InLeaf2 */
93
- /** @typedef {<T>(_: Branch3<T>) => LazyResult<T>} InBranch3 */
94
- /** @typedef {<T>(_: Branch5<T>) => LazyResult<T>} InBranch5 */
95
-
96
- /**
97
- * @typedef {{
98
- * readonly leaf1: InLeaf1
99
- * readonly leaf2_left: InLeaf2
100
- * readonly leaf2_right: InLeaf2
101
- * readonly branch3: InBranch3
102
- * readonly branch5_left: InBranch5
103
- * readonly branch5_right: InBranch5
104
- * }} Found
105
- */
106
-
107
- /**
108
- * @typedef {{
109
- * readonly leaf1_left: InLeaf1
110
- * readonly leaf1_right: InLeaf1
111
- * readonly leaf2_left: InLeaf2
112
- * readonly leaf2_middle: InLeaf2
113
- * readonly leaf2_right: InLeaf2
114
- * }} NotFound
115
- */
116
-
117
- /**
118
- * @template T
119
- * @typedef {(f: (_: Node<T>) => LazyResult<T>) => LazyResult<T>} FResult<T>
120
- */
121
-
122
- /**
123
- * @typedef {{
124
- * readonly branch3_left: <T>(branch3: Branch3<T>) => FResult<T>
125
- * readonly branch3_right: <T>(branch3: Branch3<T>) => FResult<T>
126
- * readonly branch5_left: <T>(branch5: Branch5<T>) => FResult<T>
127
- * readonly branch5_middle: <T>(branch5: Branch5<T>) => FResult<T>
128
- * readonly branch5_right: <T>(branch5: Branch5<T>) => FResult<T>
129
- * }} Continue
130
- */
131
-
132
- /**
133
- * @typedef {{
134
- * readonly found: Found
135
- * readonly notFound: NotFound
136
- * }} Visitor
137
- */
138
-
139
51
  /**
140
52
  * @template T
141
53
  * @typedef { readonly[...Branch5<T>, T, Node<T>] } Branch7
142
54
  */
143
55
 
144
- /** @type {<T>(n: Branch7<T>) => Branch3<T>} */
145
- const split = ([n0, v1, n2, v3, n4, v5, n6]) => [[n0, v1, n2], v3, [n4, v5, n6]]
146
-
147
- /**
148
- * @template T
149
- * @typedef {(init: Lazy<T>) => Result<T>} LazyResult
150
- */
151
-
152
- /**
153
- * @type {<T>(extend: (o: Branch3<T>) => Result<T>) =>
154
- * (replace: (r: Node<T>) => Node<T>) =>
155
- * (result: LazyResult<T>) =>
156
- * LazyResult<T>}
157
- */
158
- const merge = extend => replace => lazyResult => init => {
159
- const result = lazyResult(init)
160
- switch (result[0]) {
161
- case 'done': { return result }
162
- case 'replace': { return ['replace', replace(result[1])] }
163
- default: { return extend(result[1]) }
164
- }
165
- }
166
-
167
- /** @type {(visitor: Visitor) => <T>(cmp: Cmp<T>) => (node: Node<T>) => LazyResult<T>} */
168
- const visit = ({ found, notFound }) => cmp => {
169
- const i3 = index3(cmp)
170
- const i5 = index5(cmp)
171
- /** @typedef {typeof cmp extends Cmp<infer T> ? T : never} T */
172
- /**
173
- * @type {(extend: (o: Branch3<T>) => Branch5<T>) =>
174
- * (replace: (r: Node<T>) => Branch3<T>) =>
175
- * (result: LazyResult<T>) =>
176
- * LazyResult<T>}
177
- */
178
- const merge2 = extend => merge(o => ['replace', extend(o)])
179
- /**
180
- * @type {(extend: (o: Branch3<T>) => Branch7<T>) =>
181
- * (replace: (r: Node<T>) => Branch5<T>) =>
182
- * (result: LazyResult<T>) =>
183
- * LazyResult<T>}
184
- */
185
- const merge3 = extend => merge(o => ['overflow', split(extend(o))])
186
- /** @type {(node: Node<T>) => LazyResult<T>} */
187
- const f = node => {
188
- switch (node.length) {
189
- case 1: {
190
- switch (i3(node[0])) {
191
- case 0: { return notFound.leaf1_left(node) }
192
- case 1: { return found.leaf1(node) }
193
- default: { return notFound.leaf1_right(node) }
194
- }
195
- }
196
- case 2: {
197
- switch (i5(node)) {
198
- case 0: { return notFound.leaf2_left(node) }
199
- case 1: { return found.leaf2_left(node) }
200
- case 2: { return notFound.leaf2_middle(node) }
201
- case 3: { return found.leaf2_right(node) }
202
- default: { return notFound.leaf2_right(node) }
203
- }
204
- }
205
- case 3: {
206
- const [n0, v1, n2] = node
207
- switch (i3(v1)) {
208
- case 0: {
209
- return merge2
210
- (e => [...e, v1, n2])
211
- (r => [r, v1, n2])
212
- (f(n0))
213
- }
214
- case 1: { return found.branch3(node) }
215
- default: {
216
- return merge2
217
- (e => [n0, v1, ...e])
218
- (r => [n0, v1, r])
219
- (f(n2))
220
- }
221
- }
222
- }
223
- default: {
224
- const [n0, v1, n2, v3, n4] = node
225
- switch (i5([v1, v3])) {
226
- case 0: {
227
- return merge3
228
- (o => [...o, v1, n2, v3, n4])
229
- (r => [r, v1, n2, v3, n4])
230
- (f(n0))
231
- }
232
- case 1: { return found.branch5_left(node) }
233
- case 2: {
234
- return merge3
235
- (o => [n0, v1, ...o, v3, n4])
236
- (r => [n0, v1, r, v3, n4])
237
- (f(n2))
238
- }
239
- case 3: { return found.branch5_right(node) }
240
- default: {
241
- return merge3
242
- (o => [n0, v1, n2, v3, ...o])
243
- (r => [n0, v1, n2, v3, r])
244
- (f(n4))
245
- }
246
- }
247
- }
248
- }
249
- }
250
- return f
251
- }
252
-
253
- /** @type { <T>(_: T) => Done<T> } */
254
- const found = value => ['done', value]
255
-
256
- /** @type {Found} */
257
- const foundGet = {
258
- leaf1: ([value]) => () => found(value),
259
- leaf2_left: ([value]) => () => found(value),
260
- leaf2_right: ([, value]) => () => found(value),
261
- branch3: ([, value]) => () => found(value),
262
- branch5_left: ([, value]) => () => found(value),
263
- branch5_right: ([, , , value]) => () => found(value),
264
- }
265
- /** @type { () => () => NotFoundDone } */
266
- const notFound = () => () => ['done']
267
-
268
- /** @type {NotFound} */
269
- const notFoundGet = {
270
- leaf1_left: notFound,
271
- leaf1_right: notFound,
272
- leaf2_left: notFound,
273
- leaf2_middle: notFound,
274
- leaf2_right: notFound,
275
- }
276
-
277
- /** @type { <T>(_: Node<T>) => Replace<T> } */
278
- const replace = node => ['replace', node]
279
-
280
- /** @type {Found} */
281
- const foundReplace = {
282
- leaf1: () => f => replace([f()]),
283
- leaf2_left: ([, v1]) => f => replace([f(), v1]),
284
- leaf2_right: ([v0,]) => f => replace([v0, f()]),
285
- branch3: ([n0, , n2]) => f => replace([n0, f(), n2]),
286
- branch5_left: ([n0, , n2, v3, n4]) => f => replace([n0, f(), n2, v3, n4]),
287
- branch5_right: ([n0, v1, n2, , n4]) => f => replace([n0, v1, n2, f(), n4])
288
- }
289
-
290
- /** @type {<T>(leaf3: Array3<T>) => Result<T>} */
291
- const overflow = ([v0, v1, v2]) => ['overflow', [[v0], v1, [v2]]]
292
-
293
- /** @type {NotFound} */
294
- const notFoundInsert = {
295
- leaf1_left: ([v]) => f => replace([f(), v]),
296
- leaf1_right: ([v]) => f => replace([v, f()]),
297
- leaf2_left: ([v0, v1]) => f => overflow([f(), v0, v1]),
298
- leaf2_middle: ([v0, v1]) => f => overflow([v0, f(), v1]),
299
- leaf2_right: ([v0, v1]) => f => overflow([v0, v1, f()]),
300
- }
301
-
302
- /** @type {Visitor} */
303
- const getVisitor = {
304
- found: foundGet,
305
- notFound: notFoundGet,
306
- }
307
-
308
- /** @type {Visitor} */
309
- const setVisitor = {
310
- found: foundReplace,
311
- notFound: notFoundInsert,
312
- }
313
-
314
- /** @type {Visitor} */
315
- const getOrInsertVisitor = {
316
- found: foundGet,
317
- notFound: notFoundInsert,
318
- }
319
-
320
- /** @type {Visitor} */
321
- const replaceVisitor = {
322
- found: foundReplace,
323
- notFound: notFoundGet,
324
- }
325
-
326
56
  /** @type {<T>(node: Node<T>) => seq.Thunk<T>} */
327
57
  const values = node => () => {
328
58
  switch (node.length) {
@@ -351,109 +81,7 @@ const values = node => () => {
351
81
  * @typedef {readonly[Node<T>]} Branch1
352
82
  */
353
83
 
354
- /**
355
- * @template T
356
- * @typedef { Branch1<T> | Branch3<T> } ConcatResult
357
- */
358
-
359
- /**
360
- * @template T
361
- * @typedef {readonly[...Branch7<T>,T,Node<T>]} Branch9
362
- */
363
-
364
- /**
365
- * @template T
366
- * @typedef {readonly[...Branch9<T>,T,Node<T>]} Branch11
367
- */
368
-
369
- /** @type {<T>(n: Branch5<T> | Branch7<T> | Branch9<T> | Branch11<T>) => Branch1<T> | Branch3<T>} */
370
- const up = n => {
371
- switch (n.length) {
372
- case 5: { return [n] }
373
- case 7: {
374
- const [n0, v1, n2, v3, n4, v5, n6] = n
375
- return [[n0, v1, n2], v3, [n4, v5, n6]]
376
- }
377
- case 9: {
378
- const [n0, v1, n2, v3, n4, v5, n6, v7, n8] = n
379
- return [[n0, v1, n2], v3, [n4, v5, n6, v7, n8]]
380
- }
381
- case 11: {
382
- const [n0, v1, n2, v3, n4, v5, n6, v7, n8, v9, n10] = n
383
- return [[n0, v1, n2, v3, n4], v5, [n6, v7, n8, v9, n10]]
384
- }
385
- }
386
- }
387
-
388
- /**
389
- * @template T
390
- * @typedef {readonly[Node<T>,T]} Head2
391
- */
392
-
393
- /**
394
- * @template T
395
- * @typedef {readonly[...Head2<T>, ...Head2<T>]} Head4
396
- */
397
-
398
- /**
399
- * @template T
400
- * @typedef {Head2<T>|Head4<T>} Head
401
- */
402
-
403
- /** @type {<T>(n: Branch3<T> | Branch5<T>) => readonly[Head<T>, Node<T>]} */
404
- const headLast = n => {
405
- if (n.length === 3) {
406
- const [n0, v1, n2] = n
407
- return [[n0, v1], n2]
408
- } else {
409
- const [n0, v1, n2, v3, n4] = n
410
- return [[n0, v1, n2, v3], n4]
411
- }
412
- }
413
-
414
- /** @type {<T>(a: Node<T>) => (b: Node<T>) => ConcatResult<T>} */
415
- const concat = a => b => {
416
- /** @typedef {typeof a extends Node<infer T> ? T : never} T */
417
- switch (a.length) {
418
- case 1: {
419
- switch (b.length) {
420
- case 1: { return [[a[0], b[0]]] }
421
- case 2: { return [a, b[0], [b[1]]] }
422
- default: { throw 'invalid b node' }
423
- }
424
- }
425
- case 2: { return [[a[0]], a[1], b] }
426
- default: {
427
- switch (b.length) {
428
- case 3: case 5: {
429
- const [aHead, aLast] = headLast(a)
430
- const [bFirst, ...bTail] = b
431
- return up([...aHead, ...concat(aLast)(bFirst), ...bTail])
432
- }
433
- default: { throw 'invalid b node' }
434
- }
435
- }
436
- }
437
- }
438
-
439
84
  module.exports = {
440
85
  /** @readonly */
441
86
  values,
442
- /**
443
- * @readonly
444
- * @type { <T>(cmp: Cmp<T>) => (node: Node<T>) => T|undefined }
445
- */
446
- getVisitor: cmp => node => {
447
- const result = visit(getVisitor)(cmp)(node)(() => { throw 'getVisitor' })
448
- if (result[0] !== 'done') { throw 'getVisitor result' }
449
- return result[1]
450
- },
451
- /** @readonly */
452
- setVisitor: visit(setVisitor),
453
- /** @readonly */
454
- getOrInsertVisitor: visit(getOrInsertVisitor),
455
- /** @readonly */
456
- replaceVisitor: visit(replaceVisitor),
457
- /** @readonly */
458
- concat,
459
87
  }
@@ -0,0 +1,165 @@
1
+ const _ = require('..')
2
+ const { todo } = require('../../../dev')
3
+ const cmp = require('../../function/compare')
4
+ const find = require('../find')
5
+ const list = require('../../list')
6
+ const array = require('../../array')
7
+
8
+ /**
9
+ * @template T
10
+ * @typedef {undefined | _.Leaf1<T>} Leaf01
11
+ */
12
+
13
+ /**
14
+ * @template T
15
+ * @typedef {{
16
+ * readonly first: Leaf01<T>,
17
+ * readonly tail: find.Path<T>
18
+ * }} RemovePath
19
+ */
20
+
21
+ /** @type {<T>(tail: find.Path<T>) => (n: _.Node<T>) => readonly[T, RemovePath<T>]} */
22
+ const path = tail => n => {
23
+ switch (n.length) {
24
+ case 1: { return [n[0], { first: undefined, tail }] }
25
+ case 2: { return [n[0], { first: [n[1]], tail }] }
26
+ case 3: { return path({ first: [0, n], tail })(n[0]) }
27
+ case 5: { return path({ first: [0, n], tail })(n[0]) }
28
+ }
29
+ }
30
+
31
+ /**
32
+ * @template T
33
+ * @typedef {_.Branch1<T> | _.Branch3<T> | _.Branch5<T>} Branch
34
+ */
35
+
36
+ /** @type {<T>(a: Branch<T>) => (n: _.Branch3<T>) => _.Branch1<T> | _.Branch3<T>} */
37
+ const reduceValue0 = a => n => {
38
+ const [, v1, n2] = n
39
+ if (a.length === 1) {
40
+ switch (n2.length) {
41
+ case 3: { return [[a[0], v1, ...n2]] }
42
+ case 5: { return [[a[0], v1, n2[0]], n2[1], [n2[2], n2[3], n2[4]]] }
43
+ default: { throw 'invalid node' }
44
+ }
45
+ } else {
46
+ return [a, v1, n2]
47
+ }
48
+ }
49
+
50
+ /** @type {<T>(a: Branch<T>) => (n: _.Branch3<T>) => _.Branch1<T> | _.Branch3<T>} */
51
+ const reduceValue2 = a => n => {
52
+ const [n0, v1, ] = n
53
+ if (a.length === 1) {
54
+ switch (n0.length) {
55
+ case 3: { return [[...n0, v1, a[0]]] }
56
+ case 5: { return [[n0[0], n0[1], n0[2]], n0[3], [n0[4], v1, a[0]]] }
57
+ default: { throw 'invalid node' }
58
+ }
59
+ } else {
60
+ return [n0, v1, a]
61
+ }
62
+ }
63
+
64
+ /** @type {<T>(a: Leaf01<T>) => (n: _.Branch3<T>) => _.Branch1<T> | _.Branch3<T>} */
65
+ const initValue0 = a => n => {
66
+ const [, v1, n2] = n
67
+ if (a === undefined) {
68
+ switch (n2.length) {
69
+ case 1: { return [[v1, ...n2]] }
70
+ case 2: { return [[v1], n2[0], [n2[1]]] }
71
+ default: { throw 'invalid node' }
72
+ }
73
+ } else {
74
+ return [a, v1, n2]
75
+ }
76
+ }
77
+
78
+ /** @type {<T>(a: Leaf01<T>) => (n: _.Branch3<T>) => _.Branch1<T> | _.Branch3<T>} */
79
+ const initValue1 = a => n => {
80
+ const [n0, v1] = n
81
+ if (a === undefined) {
82
+ switch (n0.length) {
83
+ case 1: { return [[...n0, v1]] }
84
+ case 2: { return [[n0[0]], n0[1], [v1]] }
85
+ default: { throw 'invalid node' }
86
+ }
87
+ } else { return [n0, v1, a] }
88
+ }
89
+
90
+ /**
91
+ * @template A,T
92
+ * @typedef {(a: A) => (n: _.Branch3<T>) => _.Branch1<T> | _.Branch3<T>} Merge
93
+ */
94
+
95
+ /** @type {<A, T>(ms: array.Array2<Merge<A, T>>) => (a: A) => (i: find.PathItem<T>) => Branch<T>} */
96
+ const reduceX = ms => a => i => {
97
+ const [m0, m2] = ms
98
+ /** @typedef {typeof ms extends array.Array2<Merge<infer A, infer T>> ? [A,T] : never} AT */
99
+ /** @typedef {AT[0]} A */
100
+ /** @typedef {AT[1]} T */
101
+ /** @type {(m: Merge<A, T>) => Branch<T>} */
102
+ const f = m => {
103
+ const n = i[1]
104
+ const ra = m(a)
105
+ return n.length === 3 ? ra(n) : [...ra([n[0], n[1], n[2]]), n[3], n[4]]
106
+ }
107
+ switch (i[0]) {
108
+ case 0: { return f(m0) }
109
+ case 2: { return f(m2) }
110
+ case 4: {
111
+ const n = i[1]
112
+ return [n[0], n[1], ...m2(a)([n[2], n[3], n[4]])]
113
+ }
114
+ }
115
+ }
116
+
117
+ const reduce = list.reduce(reduceX([reduceValue0, reduceValue2]))
118
+
119
+ const initReduce = reduceX([initValue0, initValue1])
120
+
121
+ /** @type {<T>(c: cmp.Compare<T>) => (node: _.Node<T>) => undefined | _.Node<T>} */
122
+ const remove = c => node => {
123
+ /** @typedef {typeof c extends cmp.Compare<infer T> ? T : never} T */
124
+ /** @type {() => undefined | RemovePath<T>} */
125
+ const f = () => {
126
+ const { first, tail } = find.find(c)(node)
127
+ /** @type {(n: _.Node<T>) => (f: (v: T) => find.PathItem<T>) => RemovePath<T>} */
128
+ const branch = n => f => {
129
+ const [v, p] = path(/** @type {find.Path<T>} */(undefined))(n)
130
+ return { first: p.first, tail: list.concat(p.tail)({ first: f(v), tail }) }
131
+ }
132
+ switch (first[0]) {
133
+ case 1: {
134
+ const n = first[1]
135
+ switch (n.length) {
136
+ case 1: { return { first: undefined, tail } }
137
+ case 2: { return { first: [n[1]], tail } }
138
+ case 3: { return branch(n[2])(v => [2, [n[0], v, n[2]]]) }
139
+ case 5: { return branch(n[2])(v => [2, [n[0], v, n[2], n[3], n[4]]]) }
140
+ }
141
+ }
142
+ case 3: {
143
+ const n = first[1]
144
+ switch (n.length) {
145
+ case 2: { return { first: [n[0]], tail } }
146
+ case 5: { return branch(n[4])(v => [4, [n[0], n[1], n[2], v, n[4]]]) }
147
+ }
148
+ }
149
+ default: { return undefined }
150
+ }
151
+ }
152
+ const r = f()
153
+ if (r === undefined) { return node }
154
+ const { first, tail } = r
155
+ const tailR = list.next(tail)
156
+ if (tailR === undefined) { return first }
157
+ const { first: tf, tail: tt } = tailR
158
+ const result = reduce(initReduce(first)(tf))(tt)
159
+ return result.length === 1 ? result[0] : result
160
+ }
161
+
162
+ module.exports = {
163
+ /** @readonly */
164
+ remove,
165
+ }
@@ -0,0 +1,487 @@
1
+ const _ = require('.')
2
+ const btree = require('..')
3
+ const s = require('../set')
4
+ const { stringCmp } = require('../../function/compare')
5
+ const json = require('../../../json')
6
+ const { sort } = require('../../object')
7
+
8
+ /** @type {(node: btree.Node<string>) => (value: string) => btree.Node<string>} */
9
+ const set = node => value => s.set(stringCmp(value))(value)(node)
10
+
11
+ /** @type {(node: btree.Node<string>) => (value: string) => btree.Node<string> | undefined} */
12
+ const remove = node => value => _.remove(stringCmp(value))(node)
13
+
14
+ const jsonStr = json.stringify(sort)
15
+
16
+ {
17
+ /** @type {btree.Node<string> | undefined} */
18
+ let _map = ['1']
19
+ for (let i = 2; i <= 38; i++)
20
+ _map = set(_map)((i * i).toString())
21
+ {
22
+ const r = jsonStr(_map)
23
+ if (r !==
24
+ '[[[[["1"],"100",["1024"]],"1089",[["1156"],"121",["1225"]]],' +
25
+ '"1296",' +
26
+ '[[["1369"],"144",["1444"]],"16",[["169"],"196",["225"]]]],' +
27
+ '"25",' +
28
+ '[[[["256"],"289",["324"],"36",["361"]],"4",[["400"],"441",["484"]]],' +
29
+ '"49",' +
30
+ '[[["529"],"576",["625"]],"64",[["676"],"729",["784"]],"81",[["841"],"9",["900","961"]]]]]'
31
+ ) { throw r }
32
+ }
33
+ {
34
+ _map = remove(_map)("0")
35
+ if (_map === undefined) { throw 'undefined' }
36
+ const r = jsonStr(_map)
37
+ if (r !==
38
+ '[[[[["1"],"100",["1024"]],"1089",[["1156"],"121",["1225"]]],' +
39
+ '"1296",' +
40
+ '[[["1369"],"144",["1444"]],"16",[["169"],"196",["225"]]]],' +
41
+ '"25",' +
42
+ '[[[["256"],"289",["324"],"36",["361"]],"4",[["400"],"441",["484"]]],' +
43
+ '"49",' +
44
+ '[[["529"],"576",["625"]],"64",[["676"],"729",["784"]],"81",[["841"],"9",["900","961"]]]]]'
45
+ ) { throw r }
46
+ }
47
+ {
48
+ _map = remove(_map)("1")
49
+ if (_map === undefined) { throw 'undefined' }
50
+ const r = jsonStr(_map)
51
+ if (r !==
52
+ '[[[["100","1024"],"1089",["1156"],"121",["1225"]],"1296",[["1369"],"144",["1444"]],"16",[["169"],"196",["225"]]],' +
53
+ '"25",' +
54
+ '[[["256"],"289",["324"],"36",["361"]],"4",[["400"],"441",["484"]]],' +
55
+ '"49",' +
56
+ '[[["529"],"576",["625"]],"64",[["676"],"729",["784"]],"81",[["841"],"9",["900","961"]]]]'
57
+ ) { throw r }
58
+ }
59
+ {
60
+ _map = remove(_map)("4")
61
+ if (_map === undefined) { throw 'undefined' }
62
+ const r = jsonStr(_map)
63
+ if (r !==
64
+ '[[[["100","1024"],"1089",["1156"],"121",["1225"]],"1296",[["1369"],"144",["1444"]],"16",[["169"],"196",["225"]]],' +
65
+ '"25",' +
66
+ '[[["256"],"289",["324"]],"36",[["361"],"400",["441","484"]]],' +
67
+ '"49",' +
68
+ '[[["529"],"576",["625"]],"64",[["676"],"729",["784"]],"81",[["841"],"9",["900","961"]]]]'
69
+ ) { throw r }
70
+ }
71
+ {
72
+ _map = remove(_map)("9")
73
+ if (_map === undefined) { throw 'undefined' }
74
+ const r = jsonStr(_map)
75
+ if (r !==
76
+ '[[[["100","1024"],"1089",["1156"],"121",["1225"]],"1296",[["1369"],"144",["1444"]],"16",[["169"],"196",["225"]]],' +
77
+ '"25",' +
78
+ '[[["256"],"289",["324"]],"36",[["361"],"400",["441","484"]]],' +
79
+ '"49",' +
80
+ '[[["529"],"576",["625"]],"64",[["676"],"729",["784"]],"81",[["841"],"900",["961"]]]]'
81
+ ) { throw r }
82
+ }
83
+ {
84
+ _map = remove(_map)("16")
85
+ if (_map === undefined) { throw 'undefined' }
86
+ const r = jsonStr(_map)
87
+ if (r !==
88
+ '[[[["100","1024"],"1089",["1156"],"121",["1225"]],"1296",[["1369"],"144",["1444"],"169",["196","225"]]],' +
89
+ '"25",' +
90
+ '[[["256"],"289",["324"]],"36",[["361"],"400",["441","484"]]],' +
91
+ '"49",' +
92
+ '[[["529"],"576",["625"]],"64",[["676"],"729",["784"]],"81",[["841"],"900",["961"]]]]'
93
+ ) { throw r }
94
+ }
95
+ {
96
+ _map = remove(_map)("25")
97
+ if (_map === undefined) { throw 'undefined' }
98
+ const r = jsonStr(_map)
99
+ if (r !==
100
+ '[[[["100","1024"],"1089",["1156"],"121",["1225"]],"1296",[["1369"],"144",["1444"],"169",["196","225"]],"256",[["289","324"],"36",["361"],"400",["441","484"]]],' +
101
+ '"49",' +
102
+ '[[["529"],"576",["625"]],"64",[["676"],"729",["784"]],"81",[["841"],"900",["961"]]]]'
103
+ ) { throw r }
104
+ }
105
+ {
106
+ _map = remove(_map)("36")
107
+ if (_map === undefined) { throw 'undefined' }
108
+ const r = jsonStr(_map)
109
+ if (r !==
110
+ '[[[["100","1024"],"1089",["1156"],"121",["1225"]],"1296",[["1369"],"144",["1444"],"169",["196","225"]],"256",[["289"],"324",["361"],"400",["441","484"]]],' +
111
+ '"49",' +
112
+ '[[["529"],"576",["625"]],"64",[["676"],"729",["784"]],"81",[["841"],"900",["961"]]]]'
113
+ ) { throw r }
114
+ }
115
+ {
116
+ _map = remove(_map)("49")
117
+ if (_map === undefined) { throw 'undefined' }
118
+ const r = jsonStr(_map)
119
+ if (r !==
120
+ '[[[["100","1024"],"1089",["1156"],"121",["1225"]],"1296",[["1369"],"144",["1444"],"169",["196","225"]],"256",[["289"],"324",["361"],"400",["441","484"]]],' +
121
+ '"529",' +
122
+ '[[["576","625"],"64",["676"],"729",["784"]],"81",[["841"],"900",["961"]]]]'
123
+ ) { throw r }
124
+ }
125
+ {
126
+ _map = remove(_map)("64")
127
+ if (_map === undefined) { throw 'undefined' }
128
+ const r = jsonStr(_map)
129
+ if (r !==
130
+ '[[[["100","1024"],"1089",["1156"],"121",["1225"]],"1296",[["1369"],"144",["1444"],"169",["196","225"]],"256",[["289"],"324",["361"],"400",["441","484"]]],' +
131
+ '"529",' +
132
+ '[[["576"],"625",["676"],"729",["784"]],"81",[["841"],"900",["961"]]]]'
133
+ ) { throw r }
134
+ }
135
+ {
136
+ _map = remove(_map)("81")
137
+ if (_map === undefined) { throw 'undefined' }
138
+ const r = jsonStr(_map)
139
+ if (r !==
140
+ '[[[["100","1024"],"1089",["1156"],"121",["1225"]],"1296",[["1369"],"144",["1444"],"169",["196","225"]],"256",[["289"],"324",["361"],"400",["441","484"]]],' +
141
+ '"529",' +
142
+ '[[["576"],"625",["676"]],"729",[["784"],"841",["900","961"]]]]'
143
+ ) { throw r }
144
+ }
145
+ {
146
+ _map = remove(_map)("100")
147
+ if (_map === undefined) { throw 'undefined' }
148
+ const r = jsonStr(_map)
149
+ if (r !==
150
+ '[[[["1024"],"1089",["1156"],"121",["1225"]],"1296",[["1369"],"144",["1444"],"169",["196","225"]],"256",[["289"],"324",["361"],"400",["441","484"]]],' +
151
+ '"529",' +
152
+ '[[["576"],"625",["676"]],"729",[["784"],"841",["900","961"]]]]'
153
+ ) { throw r }
154
+ }
155
+ {
156
+ _map = remove(_map)("121")
157
+ if (_map === undefined) { throw 'undefined' }
158
+ const r = jsonStr(_map)
159
+ if (r !==
160
+ '[[[["1024"],"1089",["1156","1225"]],"1296",[["1369"],"144",["1444"],"169",["196","225"]],"256",[["289"],"324",["361"],"400",["441","484"]]],' +
161
+ '"529",' +
162
+ '[[["576"],"625",["676"]],"729",[["784"],"841",["900","961"]]]]'
163
+ ) { throw r }
164
+ }
165
+ {
166
+ _map = remove(_map)("144")
167
+ if (_map === undefined) { throw 'undefined' }
168
+ const r = jsonStr(_map)
169
+ if (r !==
170
+ '[[[["1024"],"1089",["1156","1225"]],"1296",[["1369","1444"],"169",["196","225"]],"256",[["289"],"324",["361"],"400",["441","484"]]],' +
171
+ '"529",' +
172
+ '[[["576"],"625",["676"]],"729",[["784"],"841",["900","961"]]]]'
173
+ ) { throw r }
174
+ }
175
+ {
176
+ _map = remove(_map)("169")
177
+ if (_map === undefined) { throw 'undefined' }
178
+ const r = jsonStr(_map)
179
+ if (r !==
180
+ '[[[["1024"],"1089",["1156","1225"]],"1296",[["1369","1444"],"196",["225"]],"256",[["289"],"324",["361"],"400",["441","484"]]],' +
181
+ '"529",' +
182
+ '[[["576"],"625",["676"]],"729",[["784"],"841",["900","961"]]]]'
183
+ ) { throw r }
184
+ }
185
+ {
186
+ _map = remove(_map)("196")
187
+ if (_map === undefined) { throw 'undefined' }
188
+ const r = jsonStr(_map)
189
+ if (r !==
190
+ '[[[["1024"],"1089",["1156","1225"]],"1296",[["1369"],"1444",["225"]],"256",[["289"],"324",["361"],"400",["441","484"]]],' +
191
+ '"529",' +
192
+ '[[["576"],"625",["676"]],"729",[["784"],"841",["900","961"]]]]'
193
+ ) { throw r }
194
+ }
195
+ {
196
+ _map = remove(_map)("225")
197
+ if (_map === undefined) { throw 'undefined' }
198
+ const r = jsonStr(_map)
199
+ if (r !==
200
+ '[[[["1024"],"1089",["1156","1225"],"1296",["1369","1444"]],"256",[["289"],"324",["361"],"400",["441","484"]]],' +
201
+ '"529",' +
202
+ '[[["576"],"625",["676"]],"729",[["784"],"841",["900","961"]]]]'
203
+ ) { throw r }
204
+ }
205
+ {
206
+ _map = remove(_map)("256")
207
+ if (_map === undefined) { throw 'undefined' }
208
+ const r = jsonStr(_map)
209
+ if (r !==
210
+ '[[[["1024"],"1089",["1156","1225"],"1296",["1369","1444"]],"289",[["324","361"],"400",["441","484"]]],' +
211
+ '"529",' +
212
+ '[[["576"],"625",["676"]],"729",[["784"],"841",["900","961"]]]]'
213
+ ) { throw r }
214
+ }
215
+ {
216
+ _map = remove(_map)("289")
217
+ if (_map === undefined) { throw 'undefined' }
218
+ const r = jsonStr(_map)
219
+ if (r !==
220
+ '[[[["1024"],"1089",["1156","1225"],"1296",["1369","1444"]],"324",[["361"],"400",["441","484"]]],' +
221
+ '"529",' +
222
+ '[[["576"],"625",["676"]],"729",[["784"],"841",["900","961"]]]]'
223
+ ) { throw r }
224
+ }
225
+ {
226
+ _map = remove(_map)("324")
227
+ if (_map === undefined) { throw 'undefined' }
228
+ const r = jsonStr(_map)
229
+ if (r !==
230
+ '[[[["1024"],"1089",["1156","1225"],"1296",["1369","1444"]],"361",[["400"],"441",["484"]]],' +
231
+ '"529",' +
232
+ '[[["576"],"625",["676"]],"729",[["784"],"841",["900","961"]]]]'
233
+ ) { throw r }
234
+ }
235
+ {
236
+ _map = remove(_map)("361")
237
+ if (_map === undefined) { throw 'undefined' }
238
+ const r = jsonStr(_map)
239
+ if (r !==
240
+ '[[[["1024"],"1089",["1156","1225"]],"1296",[["1369","1444"],"400",["441","484"]]],' +
241
+ '"529",' +
242
+ '[[["576"],"625",["676"]],"729",[["784"],"841",["900","961"]]]]'
243
+ ) { throw r }
244
+ }
245
+ {
246
+ _map = remove(_map)("400")
247
+ if (_map === undefined) { throw 'undefined' }
248
+ const r = jsonStr(_map)
249
+ if (r !==
250
+ '[[[["1024"],"1089",["1156","1225"]],"1296",[["1369","1444"],"441",["484"]]],' +
251
+ '"529",' +
252
+ '[[["576"],"625",["676"]],"729",[["784"],"841",["900","961"]]]]'
253
+ ) { throw r }
254
+ }
255
+ {
256
+ _map = remove(_map)("441")
257
+ if (_map === undefined) { throw 'undefined' }
258
+ const r = jsonStr(_map)
259
+ if (r !==
260
+ '[[[["1024"],"1089",["1156","1225"]],"1296",[["1369"],"1444",["484"]]],' +
261
+ '"529",' +
262
+ '[[["576"],"625",["676"]],"729",[["784"],"841",["900","961"]]]]'
263
+ ) { throw r }
264
+ }
265
+ {
266
+ _map = remove(_map)("484")
267
+ if (_map === undefined) { throw 'undefined' }
268
+ const r = jsonStr(_map)
269
+ if (r !==
270
+ '[[["1024"],"1089",["1156","1225"],"1296",["1369","1444"]],' +
271
+ '"529",' +
272
+ '[["576"],"625",["676"]],' +
273
+ '"729",' +
274
+ '[["784"],"841",["900","961"]]]'
275
+ ) { throw r }
276
+ }
277
+ {
278
+ _map = remove(_map)("529")
279
+ if (_map === undefined) { throw 'undefined' }
280
+ const r = jsonStr(_map)
281
+ if (r !==
282
+ '[[["1024"],"1089",["1156","1225"]],"1296",[["1369","1444"],"576",["625","676"]],' +
283
+ '"729",' +
284
+ '[["784"],"841",["900","961"]]]'
285
+ ) { throw r }
286
+ }
287
+ {
288
+ _map = remove(_map)("576")
289
+ if (_map === undefined) { throw 'undefined' }
290
+ const r = jsonStr(_map)
291
+ if (r !==
292
+ '[[["1024"],"1089",["1156","1225"]],"1296",[["1369","1444"],"625",["676"]],' +
293
+ '"729",' +
294
+ '[["784"],"841",["900","961"]]]'
295
+ ) { throw r }
296
+ }
297
+ {
298
+ _map = remove(_map)("625")
299
+ if (_map === undefined) { throw 'undefined' }
300
+ const r = jsonStr(_map)
301
+ if (r !==
302
+ '[[["1024"],"1089",["1156","1225"]],"1296",[["1369"],"1444",["676"]],' +
303
+ '"729",' +
304
+ '[["784"],"841",["900","961"]]]'
305
+ ) { throw r }
306
+ }
307
+ {
308
+ _map = remove(_map)("676")
309
+ if (_map === undefined) { throw 'undefined' }
310
+ const r = jsonStr(_map)
311
+ if (r !==
312
+ '[[["1024"],"1089",["1156","1225"],"1296",["1369","1444"]],' +
313
+ '"729",' +
314
+ '[["784"],"841",["900","961"]]]'
315
+ ) { throw r }
316
+ }
317
+ {
318
+ _map = remove(_map)("729")
319
+ if (_map === undefined) { throw 'undefined' }
320
+ const r = jsonStr(_map)
321
+ if (r !==
322
+ '[[["1024"],"1089",["1156","1225"],"1296",["1369","1444"]],' +
323
+ '"784",' +
324
+ '[["841"],"900",["961"]]]'
325
+ ) { throw r }
326
+ }
327
+ {
328
+ _map = remove(_map)("784")
329
+ if (_map === undefined) { throw 'undefined' }
330
+ const r = jsonStr(_map)
331
+ if (r !==
332
+ '[[["1024"],"1089",["1156","1225"]],"1296",[["1369","1444"],"841",["900","961"]]]'
333
+ ) { throw r }
334
+ }
335
+ {
336
+ _map = remove(_map)("841")
337
+ if (_map === undefined) { throw 'undefined' }
338
+ const r = jsonStr(_map)
339
+ if (r !==
340
+ '[[["1024"],"1089",["1156","1225"]],"1296",[["1369","1444"],"900",["961"]]]'
341
+ ) { throw r }
342
+ }
343
+ {
344
+ _map = remove(_map)("900")
345
+ if (_map === undefined) { throw 'undefined' }
346
+ const r = jsonStr(_map)
347
+ if (r !==
348
+ '[[["1024"],"1089",["1156","1225"]],"1296",[["1369"],"1444",["961"]]]'
349
+ ) { throw r }
350
+ }
351
+ {
352
+ _map = remove(_map)("961")
353
+ if (_map === undefined) { throw 'undefined' }
354
+ const r = jsonStr(_map)
355
+ if (r !==
356
+ '[["1024"],"1089",["1156","1225"],"1296",["1369","1444"]]'
357
+ ) { throw r }
358
+ }
359
+ {
360
+ _map = remove(_map)("1024")
361
+ if (_map === undefined) { throw 'undefined' }
362
+ const r = jsonStr(_map)
363
+ if (r !==
364
+ '[["1089"],"1156",["1225"],"1296",["1369","1444"]]'
365
+ ) { throw r }
366
+ }
367
+ {
368
+ _map = remove(_map)("1089")
369
+ if (_map === undefined) { throw 'undefined' }
370
+ const r = jsonStr(_map)
371
+ if (r !==
372
+ '[["1156","1225"],"1296",["1369","1444"]]'
373
+ ) { throw r }
374
+ }
375
+ {
376
+ _map = remove(_map)("1156")
377
+ if (_map === undefined) { throw 'undefined' }
378
+ const r = jsonStr(_map)
379
+ if (r !==
380
+ '[["1225"],"1296",["1369","1444"]]'
381
+ ) { throw r }
382
+ }
383
+ {
384
+ _map = remove(_map)("1225")
385
+ if (_map === undefined) { throw 'undefined' }
386
+ const r = jsonStr(_map)
387
+ if (r !==
388
+ '[["1296"],"1369",["1444"]]'
389
+ ) { throw r }
390
+ }
391
+ {
392
+ _map = remove(_map)("1296")
393
+ if (_map === undefined) { throw 'undefined' }
394
+ const r = jsonStr(_map)
395
+ if (r !==
396
+ '["1369","1444"]'
397
+ ) { throw r }
398
+ }
399
+ {
400
+ _map = remove(_map)("1369")
401
+ if (_map === undefined) { throw 'undefined' }
402
+ const r = jsonStr(_map)
403
+ if (r !== '["1444"]') { throw r }
404
+ }
405
+ {
406
+ _map = remove(_map)("1444")
407
+ if (_map !== undefined) { throw _map }
408
+ }
409
+ }
410
+
411
+ {
412
+ /** @type {btree.Node<string>|undefined} */
413
+ let _map = ['1']
414
+ for (let i = 2; i <= 10; i++)
415
+ _map = set(_map)((i * i).toString())
416
+ if (_map.length !== 3) { throw _map }
417
+ let _s = jsonStr(_map)
418
+ if (_s !== '[[["1","100"],"16",["25","36"]],"4",[["49"],"64",["81","9"]]]') { throw _s }
419
+
420
+ {
421
+ _map = remove(_map)("4")
422
+ if (_map === undefined) { throw _map }
423
+ _s = jsonStr(_map);
424
+ if (_s !== '[[["1","100"],"16",["25","36"]],"49",[["64"],"81",["9"]]]') { throw _s }
425
+ }
426
+
427
+ {
428
+ _map = remove(_map)("49")
429
+ if (_map === undefined) { throw _map }
430
+ _s = jsonStr(_map);
431
+ if (_s !== '[["1","100"],"16",["25","36"],"64",["81","9"]]') { throw _s }
432
+ }
433
+
434
+ {
435
+ _map = remove(_map)("64")
436
+ if (_map === undefined) { throw _map }
437
+ _s = jsonStr(_map);
438
+ if (_s !== '[["1","100"],"16",["25","36"],"81",["9"]]') { throw _s }
439
+ }
440
+
441
+ {
442
+ _map = remove(_map)("81")
443
+ if (_map === undefined) { throw _map }
444
+ _s = jsonStr(_map);
445
+ if (_s !== '[["1","100"],"16",["25"],"36",["9"]]') { throw _s }
446
+ }
447
+
448
+ {
449
+ _map = remove(_map)("36")
450
+ if (_map === undefined) { throw _map }
451
+ _s = jsonStr(_map);
452
+ if (_s !== '[["1","100"],"16",["25","9"]]') { throw _s }
453
+ }
454
+
455
+ {
456
+ _map = remove(_map)("16")
457
+ if (_map === undefined) { throw _map }
458
+ _s = jsonStr(_map);
459
+ if (_s !== '[["1","100"],"25",["9"]]') { throw _s }
460
+ }
461
+
462
+ {
463
+ _map = remove(_map)("25")
464
+ if (_map === undefined) { throw _map }
465
+ _s = jsonStr(_map);
466
+ if (_s !== '[["1"],"100",["9"]]') { throw _s }
467
+ }
468
+
469
+ {
470
+ _map = remove(_map)("100")
471
+ if (_map === undefined) { throw _map }
472
+ _s = jsonStr(_map);
473
+ if (_s !== '["1","9"]') { throw _s }
474
+ }
475
+
476
+ {
477
+ _map = remove(_map)("9")
478
+ if (_map === undefined) { throw _map }
479
+ _s = jsonStr(_map);
480
+ if (_s !== '["1"]') { throw _s }
481
+ }
482
+
483
+ {
484
+ _map = remove(_map)("1")
485
+ if (_map !== undefined) { throw _map }
486
+ }
487
+ }
@@ -5,13 +5,13 @@ const list = require('../../list')
5
5
 
6
6
  /**
7
7
  * @template T
8
- * @typedef {_.Branch1<T> | _.Branch3<T>} Result
8
+ * @typedef {_.Branch1<T> | _.Branch3<T>} Bracnh1To3
9
9
  */
10
10
 
11
- /** @type {<T>(b: _.Branch5<T> | _.Branch7<T>) => Result<T>} */
11
+ /** @type {<T>(b: _.Branch5<T> | _.Branch7<T>) => Bracnh1To3<T>} */
12
12
  const b57 = b => b.length === 5 ? [b] : [[b[0], b[1], b[2]], b[3], [b[4], b[5], b[6]]]
13
13
 
14
- /** @type {<T>(a: Result<T>) => (i: find.PathItem<T>) => Result<T>} */
14
+ /** @type {<T>(a: Bracnh1To3<T>) => (i: find.PathItem<T>) => Bracnh1To3<T>} */
15
15
  const reduce = a => i => {
16
16
  switch (i[0]) {
17
17
  case 0: {
@@ -39,7 +39,7 @@ const reduce = a => i => {
39
39
  const set = c => value => node => {
40
40
  const { first, tail } = find.find(c)(node)
41
41
  /** @typedef {typeof value} T */
42
- /** @type {() => Result<T>} */
42
+ /** @type {() => Bracnh1To3<T>} */
43
43
  const f = () => {
44
44
  switch (first[0]) {
45
45
  case 0: {
@@ -1,12 +1,15 @@
1
1
  const btree = require('.')
2
- const { getVisitor, setVisitor, values, concat } = btree
2
+ const { values } = btree
3
3
  const json = require('../../json')
4
4
  const { sort } = require('../object')
5
5
  const { stringCmp } = require('../function/compare')
6
6
  const list = require('../list')
7
+ const s = require('./set')
8
+ const f = require('./find')
7
9
 
8
10
  require('./find/test')
9
11
  require('./set/test')
12
+ require('./remove/test')
10
13
 
11
14
  const jsonStr = json.stringify(sort)
12
15
 
@@ -14,13 +17,7 @@ const jsonStr = json.stringify(sort)
14
17
  const stringify = sequence => jsonStr(list.toArray(sequence))
15
18
 
16
19
  /** @type {(node: btree.Node<string>) => (value: string) => btree.Node<string>} */
17
- const set = node => value => {
18
- const result = setVisitor(stringCmp(value))(node)(() => value)
19
- switch (result[0]) {
20
- case 'replace': case 'overflow': { return result[1] }
21
- default: { return node }
22
- }
23
- }
20
+ const set = node => value => s.set(stringCmp(value))(value)(node)
24
21
 
25
22
  {
26
23
  /** @type {btree.Node<string>} */
@@ -48,8 +45,8 @@ const set = node => value => {
48
45
  let _map = ['a']
49
46
  _map = set(_map)('b')
50
47
  _map = set(_map)('c')
51
- const result = getVisitor(stringCmp('b'))(_map)
52
- if (result === undefined) { throw result }
48
+ const result = f.value(f.find(stringCmp('b'))(_map).first)
49
+ if (result !== 'b') { throw result }
53
50
  }
54
51
 
55
52
  {
@@ -57,52 +54,10 @@ const set = node => value => {
57
54
  let _map = ['a']
58
55
  _map = set(_map)('b')
59
56
  _map = set(_map)('c')
60
- const result = getVisitor(stringCmp('e'))(_map)
57
+ const result = f.value(f.find(stringCmp('e'))(_map).first)
61
58
  if (result !== undefined) { throw result }
62
59
  }
63
60
 
64
- {
65
- /** @type {btree.Node<string>} */
66
- let _map = ['1']
67
- for (let i = 2; i <= 10; i++)
68
- _map = set(_map)((i * i).toString())
69
- if (_map.length !== 3) { throw _map }
70
- let _s = jsonStr(_map)
71
- if (_s !== '[[["1","100"],"16",["25","36"]],"4",[["49"],"64",["81","9"]]]') { throw _s }
72
-
73
- let [a,,b] = _map
74
- let _c = concat(a)(b)
75
- if (_c.length !== 3) { throw _c }
76
- _s =jsonStr(_c);
77
- if (_s !== '[[["1","100"],"16",["25"]],"36",[["49"],"64",["81","9"]]]') { throw _s }
78
-
79
- [a,,b] = _c
80
- _c = concat(a)(b)
81
- if (_c.length !== 1) { throw _c }
82
- _s = jsonStr(_c);
83
- if (_s !== '[[["1","100"],"16",["25","49"],"64",["81","9"]]]') { throw _s }
84
-
85
- let [_r] = _c
86
- if (_r.length !== 5) { throw _r }
87
- [a,,b] = _r
88
- _c = concat(a)(b)
89
- if (_c.length !== 3) { throw _c }
90
- _s = jsonStr(_c);
91
- if (_s !== '[["1"],"100",["25","49"]]') { throw _s }
92
-
93
- [a,,b] = _c
94
- _c = concat(a)(b)
95
- if (_c.length !== 3) { throw _c }
96
- _s = jsonStr(_c);
97
- if (_s !== '[["1"],"25",["49"]]') { throw _s }
98
-
99
- [a,,b] = _c
100
- _c = concat(a)(b)
101
- if (_c.length !== 1) { throw _c }
102
- _s = jsonStr(_c);
103
- if (_s !== '[["1","49"]]') { throw _s }
104
- }
105
-
106
61
  const test = () => {
107
62
  /** @type {btree.Node<string>} */
108
63
  let _map = ['a']
@@ -1,6 +1,8 @@
1
1
  const option = require("../option")
2
2
  const btree = require('../btree')
3
- const { getVisitor, setVisitor, values } = require("../btree")
3
+ const { values } = require("../btree")
4
+ const find = require('../btree/find')
5
+ const s = require('../btree/set')
4
6
  const compare = require("../function/compare")
5
7
  const { stringCmp } = require("../function/compare")
6
8
  const list = require("../list")
@@ -38,7 +40,7 @@ const keyCmp = a => ([b]) => stringCmp(a)(b)
38
40
  /** @type {(name: string) => <T>(map: Map<T>) => T|undefined} */
39
41
  const at = name => map => {
40
42
  if (map === undefined) { return undefined }
41
- const result = getVisitor(keyCmp(name))(map)
43
+ const result = find.value(find.find(keyCmp(name))(map).first)
42
44
  return result === undefined ? undefined : result[1]
43
45
  }
44
46
 
@@ -47,11 +49,7 @@ const set = name => value => map => {
47
49
  /** @type {Entry<typeof value>} */
48
50
  const entry = [name, value]
49
51
  if (map === undefined) { return [entry] }
50
- const result = setVisitor(keyCmp(name))(map)(() => entry)
51
- switch (result[0]) {
52
- case 'replace': case 'overflow': { return result[1] }
53
- default: { throw 'invalid BTree operation' }
54
- }
52
+ return s.set(keyCmp(name))(entry)(map)
55
53
  }
56
54
 
57
55
  /** @type {<T>(map: Map<T>) => list.List<Entry<T>>} */