functionalscript 0.0.278 → 0.0.282

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.278",
3
+ "version": "0.0.282",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/test.js CHANGED
@@ -9,6 +9,7 @@ require('./io/commonjs/test')
9
9
  require('./commonjs/package/dependencies/test')
10
10
  require('./commonjs/package/test')
11
11
  require('./commonjs/path/test')
12
+ require('./types/function/compare/test')
12
13
 
13
14
  /** @type {() => never} */
14
15
  const assert = () => { throw 'assert' }
@@ -2,7 +2,7 @@
2
2
 
3
3
  https://en.wikipedia.org/wiki/B-tree
4
4
 
5
- ## BTree 2-3 nodes
5
+ ## BTree 2-3 nodes
6
6
 
7
7
  `Node<T>`:
8
8
 
@@ -66,7 +66,7 @@ Posible actions:
66
66
  |left | 0|`[(L VM R) v1 n2]` |
67
67
  |right | 2|`[n0 v1 (L VM R)]` |
68
68
 
69
- ## Branch5 Overflow
69
+ ## Branch5 Overflow
70
70
 
71
71
  - current `[n0, v1, n2, v3, n4]`
72
72
  - overflow `[L, VM, R]`
@@ -76,3 +76,56 @@ Posible actions:
76
76
  |left | 0|`[...o v1 n2 v3 n4]`|`[(L VM R) v1 n2 v3 n4]`|`[[ L VM R ] v1 [n2 v3 n4]]`|
77
77
  |middle| 2|`[n0 v1 ...o v3 n4]`|`[n0 v1 (L VM R) v3 n4]`|`[[n0 v1 L ] VM [ R v3 n4]]`|
78
78
  |right | 4|`[n0 v1 n2 v3 ...o]`|`[n0 v1 n2 v3 (L VM R)]`|`[[n0 v1 n2] v3 [ L VM R ]]`|
79
+
80
+ ## Deleting a Node
81
+
82
+ |type |index| | | |
83
+ |------------------|-----|---------------------|--------|-----------------------------|
84
+ |`[v]` | 0| | |underflow `undefined` |
85
+ |`[v0,v1]` | 0| | |replace `[v1]` |
86
+ | | 1| | |replace `[v0]` |
87
+ |`[n0,v1,n2]` | 1|`concat(n0,n2)` |overflow|replace `[n0_,v1_,n1_]` |
88
+ | | | |replace |underflow `n_` |
89
+ |`[n0,v1,n2,v3,n4]`| 1|`concat(n0,n2),v3,n4`|overflow|replace `[n0_,v1_,n1_,v3,n4]`|
90
+ | | | |replace |replace `[n_,v3,n4]` |
91
+ | | 3|`n0,v1,concat(n2,n4)`|overflow|replace `[n0,v1,n0_,v1_,n1_]`|
92
+ | | | |replace |replace `[n0,v1,n_]` |
93
+
94
+ ### Underflow
95
+
96
+ |type |index| | |
97
+ |------------------|-----|---------------------------------------|-----------------------------------------------|
98
+ |`[n0,v1,n2]` | 0|`[[],v1,[v20]]` |underflow `[v1,v20]` |
99
+ | | |`[[],v1,[v20,v21]]` |replace `[[v1],v20,[v21]]` |
100
+ | | |`[[n_],v1,[n20,v21,n22]]` |underflow `[n_,v1,n20,v21,n22]` |
101
+ | | |`[[n_],v1,[n20,v21,n22,v23,n24]]` |replace `[[n_,v1,n20],v21,[n22,v23,n24]]` |
102
+ | | 2| | |
103
+ |`[n0,v1,n2,v3,n4]`| 0|`[[],v1,[v20],v3,n4]` |replace `[[v1,v20],v3,n4]` |
104
+ | | |`[[],v1,[v20,v21],v3,n4]` |replace `[[v1],v20,[v21],v3,n4]` |
105
+ | | |`[[n_],v1,[n20,v21,n22],v3,n4]` |replace `[[n_,v1,n20,v21,n22],v3,n4]` |
106
+ | | |`[[n_],v1,[n20,v21,n22,v23,n24],v3,n4]`|replace `[[n_,v1,n20],v21,[n22,v23,n24],v3,n4]`|
107
+ | | 2| | |
108
+ | | 4| | |
109
+
110
+ ## Concat (n0,n1)
111
+
112
+ `concat` returns either `overflow 3` or `replace`:
113
+ - `overflow 3`: `[n0,v1,n2]`
114
+ - `replace`: `n`
115
+
116
+ |`n0` |`n1` | |
117
+ |-----------------------|-----------------------|-------------------------------------------------|
118
+ |`[v00]` |`[v10]` |R `[v00,v10]` |
119
+ | |`[v10,v11]` |O `[[v00],v10,[v11]]` |
120
+ |`[v00,v01]` |`n1` |O `[[v00],v01,n1]` |
121
+ |`[n00,v01,n02]` |`[n10,v11,n12]` |`n00,v01,concat(n02,n10),v11,n12` |
122
+ | |`[n10,v11,n12,v13,n14]`|`n00,v01,concat(n02,n10),v11,n12,v13,n14` |
123
+ |`[n00,v01,n02,v03,n04]`|`[n10,v11,n12]` |`n00,v01,n02,v03,concat(n04,n10),v11,n12` |
124
+ | |`[n10,v11,n12,v13,n14]`|`n00,v01,n02,v03,concat(n04,n10),v11,n12,v13,n14`|
125
+
126
+ |source |replace `cn` |overflow `[cn0,cv1,cn2]` |
127
+ |---------------------------------------|------------------------------------|---------------------------------------------|
128
+ |`n0,v1,concat(n2,n3),v4,n5` |R `[n0,v1,cn,v2,n3]` |O `[[n0,v1,cn0],cv1,[cn2,v4,n5]]` |
129
+ |`n0,v1,concat(n2,n3),v4,n5,v6,n7` |O `[[n0,v1,cn],v4,[n5,v6,n7]]` |O `[[n0,v1,cn0],cv1,[cn2,v4,n5,v6,n7]]` |
130
+ |`n0,v1,n2,v3,concat(n4,n5),v6,n7` |O `[[n0,v1,n2],v3,[cn,v6,n7]]` |O `[[n0,v1,n2,v3,cn0],cv1,[cn2,v6,n7]]` |
131
+ |`n0,v1,n2,v3,concat(n4,n5),v6,n7,v8,n9`|O `[[n0,v1,n2],v3,[cn,v6,n7,v8,n9]]`|O `[[n0,v1,n2,v3,cn0],cv1,[cn2,v6,n7,v8,n9]]`|
@@ -1,3 +1,4 @@
1
+ const { todo } = require('../../dev')
1
2
  const cmp = require('../function/compare')
2
3
  const { index3, index5 } = cmp
3
4
  const seq = require('../list')
@@ -87,10 +88,10 @@ const seq = require('../list')
87
88
  * @typedef { Done<T> | Replace<T> | Overflow<T> } Result
88
89
  */
89
90
 
90
- /** @typedef {<T>(_: Lazy<T>) => (_: Leaf1<T>) => Result<T>} InLeaf1 */
91
- /** @typedef {<T>(_: Lazy<T>) => (_: Leaf2<T>) => Result<T>} InLeaf2 */
92
- /** @typedef {<T>(_: Lazy<T>) => (_: Branch3<T>) => Result<T>} InBranch3 */
93
- /** @typedef {<T>(_: Lazy<T>) => (_: Branch5<T>) => Result<T>} InBranch5 */
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 */
94
95
 
95
96
  /**
96
97
  * @typedef {{
@@ -113,6 +114,21 @@ const seq = require('../list')
113
114
  * }} NotFound
114
115
  */
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
+
116
132
  /**
117
133
  * @typedef {{
118
134
  * readonly found: Found
@@ -122,19 +138,25 @@ const seq = require('../list')
122
138
 
123
139
  /**
124
140
  * @template T
125
- * @typedef { readonly [Node<T>, T, Node<T>, T, Node<T>, T, Node<T>] } Branch7
141
+ * @typedef { readonly[...Branch5<T>, T, Node<T>] } Branch7
126
142
  */
127
143
 
128
144
  /** @type {<T>(n: Branch7<T>) => Branch3<T>} */
129
145
  const split = ([n0, v1, n2, v3, n4, v5, n6]) => [[n0, v1, n2], v3, [n4, v5, n6]]
130
146
 
147
+ /**
148
+ * @template T
149
+ * @typedef {(init: Lazy<T>) => Result<T>} LazyResult
150
+ */
151
+
131
152
  /**
132
153
  * @type {<T>(extend: (o: Branch3<T>) => Result<T>) =>
133
154
  * (replace: (r: Node<T>) => Node<T>) =>
134
- * (result: Result<T>) =>
135
- * Result<T>}
155
+ * (result: LazyResult<T>) =>
156
+ * LazyResult<T>}
136
157
  */
137
- const merge = extend => replace => result => {
158
+ const merge = extend => replace => lazyResult => init => {
159
+ const result = lazyResult(init)
138
160
  switch (result[0]) {
139
161
  case 'done': { return result }
140
162
  case 'replace': { return ['replace', replace(result[1])] }
@@ -142,7 +164,7 @@ const merge = extend => replace => result => {
142
164
  }
143
165
  }
144
166
 
145
- /** @type {(visitor: Visitor) => <T>(cmp: Cmp<T>) => (init: Lazy<T>) => (node: Node<T>) => Result<T>} */
167
+ /** @type {(visitor: Visitor) => <T>(cmp: Cmp<T>) => (node: Node<T>) => LazyResult<T>} */
146
168
  const visit = ({ found, notFound }) => cmp => {
147
169
  const i3 = index3(cmp)
148
170
  const i5 = index5(cmp)
@@ -150,84 +172,82 @@ const visit = ({ found, notFound }) => cmp => {
150
172
  /**
151
173
  * @type {(extend: (o: Branch3<T>) => Branch5<T>) =>
152
174
  * (replace: (r: Node<T>) => Branch3<T>) =>
153
- * (result: Result<T>) =>
154
- * Result<T>}
175
+ * (result: LazyResult<T>) =>
176
+ * LazyResult<T>}
155
177
  */
156
178
  const merge2 = extend => merge(o => ['replace', extend(o)])
157
179
  /**
158
180
  * @type {(extend: (o: Branch3<T>) => Branch7<T>) =>
159
181
  * (replace: (r: Node<T>) => Branch5<T>) =>
160
- * (result: Result<T>) =>
161
- * Result<T>}
182
+ * (result: LazyResult<T>) =>
183
+ * LazyResult<T>}
162
184
  */
163
185
  const merge3 = extend => merge(o => ['overflow', split(extend(o))])
164
- return init => {
165
- /** @type {(node: Node<T>) => Result<T>} */
166
- const f = node => {
167
- switch (node.length) {
168
- case 1: {
169
- switch (i3(node[0])) {
170
- case 0: { return notFound.leaf1_left(init)(node) }
171
- case 1: { return found.leaf1(init)(node) }
172
- default: { return notFound.leaf1_right(init)(node) }
173
- }
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) }
174
194
  }
175
- case 2: {
176
- switch (i5(node)) {
177
- case 0: { return notFound.leaf2_left(init)(node) }
178
- case 1: { return found.leaf2_left(init)(node) }
179
- case 2: { return notFound.leaf2_middle(init)(node) }
180
- case 3: { return found.leaf2_right(init)(node) }
181
- default: { return notFound.leaf2_right(init)(node) }
182
- }
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) }
183
203
  }
184
- case 3: {
185
- const [n0, v1, n2] = node
186
- switch (i3(v1)) {
187
- case 0: {
188
- return merge2
189
- (e => [...e, v1, n2])
190
- (r => [r, v1, n2])
191
- (f(n0))
192
- }
193
- case 1: { return found.branch3(init)(node) }
194
- default: {
195
- return merge2
196
- (e => [n0, v1, ...e])
197
- (r => [n0, v1, r])
198
- (f(n2))
199
- }
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))
200
220
  }
201
221
  }
202
- default: {
203
- const [n0, v1, n2, v3, n4] = node
204
- switch (i5([v1, v3])) {
205
- case 0: {
206
- return merge3
207
- (o => [...o, v1, n2, v3, n4])
208
- (r => [r, v1, n2, v3, n4])
209
- (f(n0))
210
- }
211
- case 1: { return found.branch5_left(init)(node) }
212
- case 2: {
213
- return merge3
214
- (o => [n0, v1, ...o, v3, n4])
215
- (r => [n0, v1, r, v3, n4])
216
- (f(n2))
217
- }
218
- case 3: { return found.branch5_right(init)(node) }
219
- default: {
220
- return merge3
221
- (o => [n0, v1, n2, v3, ...o])
222
- (r => [n0, v1, n2, v3, r])
223
- (f(n4))
224
- }
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))
225
245
  }
226
246
  }
227
247
  }
228
248
  }
229
- return f
230
249
  }
250
+ return f
231
251
  }
232
252
 
233
253
  /** @type { <T>(_: T) => Done<T> } */
@@ -235,12 +255,12 @@ const found = value => ['done', value]
235
255
 
236
256
  /** @type {Found} */
237
257
  const foundGet = {
238
- leaf1: () => ([value]) => found(value),
239
- leaf2_left: () => ([value]) => found(value),
240
- leaf2_right: () => ([, value]) => found(value),
241
- branch3: () => ([, value]) => found(value),
242
- branch5_left: () => ([, value]) => found(value),
243
- branch5_right: () => ([, , , value]) => found(value),
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),
244
264
  }
245
265
  /** @type { () => () => NotFoundDone } */
246
266
  const notFound = () => () => ['done']
@@ -259,12 +279,12 @@ const replace = node => ['replace', node]
259
279
 
260
280
  /** @type {Found} */
261
281
  const foundReplace = {
262
- leaf1: f => () => replace([f()]),
263
- leaf2_left: f => ([, v1]) => replace([f(), v1]),
264
- leaf2_right: f => ([v0,]) => replace([v0, f()]),
265
- branch3: f => ([n0, , n2]) => replace([n0, f(), n2]),
266
- branch5_left: f => ([n0, , n2, v3, n4]) => replace([n0, f(), n2, v3, n4]),
267
- branch5_right: f => ([n0, v1, n2, , n4]) => replace([n0, v1, n2, f(), n4])
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])
268
288
  }
269
289
 
270
290
  /** @type {<T>(leaf3: Array3<T>) => Result<T>} */
@@ -272,11 +292,11 @@ const overflow = ([v0, v1, v2]) => ['overflow', [[v0], v1, [v2]]]
272
292
 
273
293
  /** @type {NotFound} */
274
294
  const notFoundInsert = {
275
- leaf1_left: f => ([v]) => replace([f(), v]),
276
- leaf1_right: f => ([v]) => replace([v, f()]),
277
- leaf2_left: f => ([v0, v1]) => overflow([f(), v0, v1]),
278
- leaf2_middle: f => ([v0, v1]) => overflow([v0, f(), v1]),
279
- leaf2_right: f => ([v0, v1]) => overflow([v0, v1, f()]),
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()]),
280
300
  }
281
301
 
282
302
  /** @type {Visitor} */
@@ -303,7 +323,7 @@ const replaceVisitor = {
303
323
  notFound: notFoundGet,
304
324
  }
305
325
 
306
- /** @type {<T>(node: Node<T>) => seq.List<T>} */
326
+ /** @type {<T>(node: Node<T>) => seq.Thunk<T>} */
307
327
  const values = node => () => {
308
328
  switch (node.length) {
309
329
  case 1: case 2: { return node }
@@ -326,6 +346,91 @@ const values = node => () => {
326
346
  }
327
347
  }
328
348
 
349
+ /**
350
+ * @template T
351
+ * @typedef {readonly[Node<T>]} Branch1
352
+ */
353
+
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
+ /** @type {<T>(n: Branch3<T> | Branch5<T>) => readonly[Head2<T>|Head4<T>, Node<T>]} */
399
+ const bracnhSplit = n => {
400
+ if (n.length === 3) {
401
+ const [n0, v1, n2] = n
402
+ return [[n0, v1], n2]
403
+ } else {
404
+ const [n0, v1, n2, v3, n4] = n
405
+ return [[n0, v1, n2, v3], n4]
406
+ }
407
+ }
408
+
409
+ /** @type {<T>(a: Node<T>) => (b: Node<T>) => ConcatResult<T>} */
410
+ const concat = a => b => {
411
+ /** @typedef {typeof a extends Node<infer T> ? T : never} T */
412
+ switch (a.length) {
413
+ case 1: {
414
+ switch (b.length) {
415
+ case 1: { return [[a[0], b[0]]] }
416
+ case 2: { return [a, b[0], [b[1]]] }
417
+ default: { throw 'invalid b node' }
418
+ }
419
+ }
420
+ case 2: { return [[a[0]], a[1], b] }
421
+ default: {
422
+ switch (b.length) {
423
+ case 3: case 5: {
424
+ const [aHead, aLast] = bracnhSplit(a)
425
+ const [bn0, ...b1] = b
426
+ return up([...aHead, ...concat(aLast)(bn0), ...b1])
427
+ }
428
+ default: { throw 'invalid b node' }
429
+ }
430
+ }
431
+ }
432
+ }
433
+
329
434
  module.exports = {
330
435
  /** @readonly */
331
436
  values,
@@ -334,14 +439,16 @@ module.exports = {
334
439
  * @type { <T>(cmp: Cmp<T>) => (node: Node<T>) => T|undefined }
335
440
  */
336
441
  getVisitor: cmp => node => {
337
- const result = visit(getVisitor)(cmp)(() => { throw 'getVisitor' })(node)
338
- if (result[0] === 'done') { return result[1] }
339
- return undefined
442
+ const result = visit(getVisitor)(cmp)(node)(() => { throw 'getVisitor' })
443
+ if (result[0] !== 'done') { throw 'getVisitor result' }
444
+ return result[1]
340
445
  },
341
446
  /** @readonly */
342
447
  setVisitor: visit(setVisitor),
343
448
  /** @readonly */
344
449
  getOrInsertVisitor: visit(getOrInsertVisitor),
345
450
  /** @readonly */
346
- replaceVisitor: visit(replaceVisitor)
451
+ replaceVisitor: visit(replaceVisitor),
452
+ /** @readonly */
453
+ concat,
347
454
  }
@@ -1,17 +1,92 @@
1
1
  const btree = require('.')
2
- const { setVisitor, values } = btree
3
- const { cmp } = require('../function/compare')
2
+ const { getVisitor, setVisitor, values, concat } = btree
3
+ const json = require('../../json')
4
+ const { sort } = require('../object')
5
+ const { stringCmp } = require('../function/compare')
4
6
  const list = require('../list')
5
7
 
8
+ /** @type {(sequence: list.List<json.Unknown>) => string} */
9
+ const stringify = sequence => json.stringify(sort)(list.toArray(sequence))
10
+
6
11
  /** @type {(node: btree.Node<string>) => (value: string) => btree.Node<string>} */
7
12
  const set = node => value => {
8
- const result = setVisitor(cmp(value))(() => value)(node)
13
+ const result = setVisitor(stringCmp(value))(node)(() => value)
9
14
  switch (result[0]) {
10
15
  case 'replace': case 'overflow': { return result[1] }
11
16
  default: { return node }
12
17
  }
13
18
  }
14
19
 
20
+ {
21
+ /** @type {btree.Node<string>} */
22
+ let _map = ['a']
23
+ _map = set(_map)('b')
24
+ _map = set(_map)('c')
25
+ _map = set(_map)('d')
26
+ _map = set(_map)('e')
27
+ _map = set(_map)('f')
28
+ let result = stringify(values(_map))
29
+ if (result !== '["a","b","c","d","e","f"]') { throw result }
30
+ }
31
+
32
+ {
33
+ /** @type {btree.Node<string>} */
34
+ let _map = ['1']
35
+ for(let i = 2; i <= 10; i++)
36
+ _map = set(_map)((i*i).toString())
37
+ let result = stringify(values(_map))
38
+ if (result !== '["1","100","16","25","36","4","49","64","81","9"]') { throw result }
39
+ }
40
+
41
+ {
42
+ /** @type {btree.Node<string>} */
43
+ let _map = ['a']
44
+ _map = set(_map)('b')
45
+ _map = set(_map)('c')
46
+ const result = getVisitor(stringCmp('b'))(_map)
47
+ if (result === undefined) { throw result }
48
+ }
49
+
50
+ {
51
+ /** @type {btree.Node<string>} */
52
+ let _map = ['a']
53
+ _map = set(_map)('b')
54
+ _map = set(_map)('c')
55
+ const result = getVisitor(stringCmp('e'))(_map)
56
+ if (result !== undefined) { throw result }
57
+ }
58
+
59
+ {
60
+ /** @type {btree.Node<string>} */
61
+ let _map = ['1']
62
+ for (let i = 2; i <= 10; i++)
63
+ _map = set(_map)((i * i).toString())
64
+ if (_map.length !== 3) { throw _map }
65
+ // console.log(_map)
66
+ let [a,,b] = _map
67
+ let _c = concat(a)(b)
68
+ // console.log(_c)
69
+ if (_c.length !== 3) { throw _c }
70
+ [a,,b] = _c
71
+ _c = concat(a)(b)
72
+ // console.log(_c)
73
+ if (_c.length !== 1) { throw _c }
74
+ let [_r] = _c
75
+ if (_r.length !== 5) { throw _r }
76
+ [a,,b] = _r
77
+ _c = concat(a)(b)
78
+ // console.log(_c)
79
+ if (_c.length !== 3) { throw _c }
80
+ [a,,b] = _c
81
+ _c = concat(a)(b)
82
+ // console.log(_c)
83
+ if (_c.length !== 3) { throw _c }
84
+ [a,,b] = _c
85
+ _c = concat(a)(b)
86
+ // console.log(_c)
87
+ if (_c.length !== 1) { throw _c }
88
+ }
89
+
15
90
  const test = () => {
16
91
  /** @type {btree.Node<string>} */
17
92
  let _map = ['a']
@@ -3,7 +3,7 @@
3
3
 
4
4
  /**
5
5
  * @template T
6
- * @typedef {import('../../array').Array2<T>} Array2
6
+ * @typedef {import('../../array').Array2<T>} Array2
7
7
  */
8
8
 
9
9
  /** @typedef {-1|0|1} Sign */
@@ -22,8 +22,14 @@ const index5 = cmp => ([v0, v1]) => {
22
22
  return /** @type {Index5} */ (_0 <= 0 ? _0 + 1 : cmp(v1) + 3)
23
23
  }
24
24
 
25
+ /** @type {<T>(a: T) => (b: T) => Sign} */
26
+ const unsafeCmp = a => b => a < b ? -1 : a === b ? 0 : 1
27
+
25
28
  /** @type {(a: string) => (b: string) => Sign} */
26
- const cmp = a => b => a < b ? -1 : a === b ? 0 : 1
29
+ const stringCmp = unsafeCmp
30
+
31
+ /** @type {(a: number) => (b: number) => Sign} */
32
+ const numberCmp = unsafeCmp
27
33
 
28
34
  module.exports = {
29
35
  /** @readonly */
@@ -31,5 +37,7 @@ module.exports = {
31
37
  /** @readonly */
32
38
  index5,
33
39
  /** @readonly */
34
- cmp,
40
+ stringCmp,
41
+ /** @readonly */
42
+ numberCmp,
35
43
  }
@@ -0,0 +1,13 @@
1
+ const _ = require('.')
2
+
3
+ {
4
+ const result = _.numberCmp(4)(5)
5
+ if (result !== -1) { throw result }
6
+ }
7
+
8
+ {
9
+ const result = _.stringCmp('3')('4')
10
+ if (result !== -1) { throw result }
11
+ }
12
+
13
+ module.exports = {}
@@ -2,7 +2,7 @@ const option = require("../option")
2
2
  const btree = require('../btree')
3
3
  const { getVisitor, setVisitor, values } = require("../btree")
4
4
  const compare = require("../function/compare")
5
- const { cmp } = require("../function/compare")
5
+ const { stringCmp } = require("../function/compare")
6
6
  const list = require("../list")
7
7
 
8
8
  /** @typedef {compare.Sign} Sign */
@@ -33,7 +33,7 @@ const list = require("../list")
33
33
  */
34
34
 
35
35
  /** @type {(a: string) => <T>(b: Entry<T>) => Sign} */
36
- const keyCmp = a => ([b]) => cmp(a)(b)
36
+ const keyCmp = a => ([b]) => stringCmp(a)(b)
37
37
 
38
38
  /** @type {(name: string) => <T>(map: Map<T>) => T|undefined} */
39
39
  const at = name => map => {
@@ -47,7 +47,7 @@ const set = name => value => map => {
47
47
  /** @type {Entry<typeof value>} */
48
48
  const entry = [name, value]
49
49
  if (map === undefined) { return [entry] }
50
- const result = setVisitor(keyCmp(name))(() => entry)(map)
50
+ const result = setVisitor(keyCmp(name))(map)(() => entry)
51
51
  switch (result[0]) {
52
52
  case 'replace': case 'overflow': { return result[1] }
53
53
  default: { throw 'invalid BTree operation' }