functionalscript 0.0.279 → 0.0.283

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.279",
3
+ "version": "0.0.283",
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,83 @@ 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
+ ## Concat
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|
90
+
91
+ ## Up
92
+
93
+ `up` returns `Branch1` or `Branch3`
94
+
95
+ |`n.lenght`| |
96
+ |----------|--------------------------|
97
+ |5 |`[n]` |
98
+ |7 |`[n[0...2],n[3],n[4...6]]`|
99
+ |9 |`[n[0...2],n[3],n[4...8]]`|
100
+ |11 |`[n[0...4],n[5],n[6...A]]`|
101
+
102
+ ## Delete
103
+
104
+ `delete` returns `['leaf', [] | Leaf1]` | `['branch', Branch1 | Branch3 | Branch5]`
105
+
106
+ |type |index|r |
107
+ |------------------|-----|---------------------------------|
108
+ |`[v]` | 0|leaf `[]` |
109
+ |`[v0,v1]` | 0|leaf `[v1]` |
110
+ | | 1|leaf `[v2]` |
111
+ |`[n0,v1,n2]` | 1|branch `concat(n0,n2)` |
112
+ |`[n0,v1,n2,v3,n4]`| 1|branch `[...concat(n0,n2),v3,n4]`|
113
+ | | 3|branch `[n0,v1,...concat(n2,n4)]`|
114
+
115
+ |type |index|nR | |
116
+ |------------------|-----|-------|----------------------------------------|
117
+ |`[n0,v1,n2]` | 0|`[]` |`[[v1, v20]]` |
118
+ | | | |`[[v1],v20,[v21]]` |
119
+ | | |`[nR0]`|`[[nR0, v1, n20, v21, n22]]` |
120
+ | | | |`[[nR0, v1, n20], v21, [n22, v23, n23]]`|
121
+ | | |`nR` |`[r,v1,n2]` |
122
+ | | 2|`[]` |`[[v00, v1]]` |
123
+ | | | |`[[v00],v01,[v1]]` |
124
+ | | |`[nR0]`|`[[n00, v01, n02, v1, nR0]]` |
125
+ | | | |`[[n00, v01, n02], v02, [n03, v1, nR0]]`|
126
+ | | |`nR` |`[n0,v1,r]` |
127
+ |`[n0,v1,n2,v3,n4]`| 0|`[]` |`[[v1,v20],v3,n4]` |
128
+ | | | |`[[v1],v20,[v21],v3,n4]` |
129
+ | | |`[nR0]`|`[[nR0,v1,n20,v21,n22],v3,n4]` |
130
+ | | | |`[[nR0,v1,n20],v21,[n22,v23,n24],v3,n4]`|
131
+ | | |`nR` |`[nR,v1,n2,v3,n4]` |
132
+ | | 2|`[]` |`[[v00,v1],v3,n4]` |
133
+ | | | |`[[v00],v01,[v1],v3,n4]` |
134
+ | | |`[nR0]`|`[[n00,v01,n02,v1,nR0],v3,n4]` |
135
+ | | | |`[[n00,v01,n02],v03,[n04,v1,nR0],v3,n4]`|
136
+ | | |`nR` |`[n0,v1,nR,v2,n4]` |
137
+ | | 4|`[]` |`[n0,v1,[v20,v3]]` |
138
+ | | | |`[n0,v1,[v20],v21,[v3]]` |
139
+ | | |`[nR0]`|`[n0,v1,[n20,v21,n22,v3,nR0]]` |
140
+ | | | |`[n0,v1,[n20,v21,n22],v23,[n24,v3,nR0]]`|
141
+ | | |`nR` |`[n0,v1,n2,v3,nR]` |
142
+
143
+ ## Insert
144
+
145
+ `insert` returns `Branch1` or `Branch3`
146
+
147
+ |type | |size|
148
+ |------------------|---------------------------------|----|
149
+ |`[v]` |`[[vI,v]]` | |
150
+ | |`[[v,vI]]` | |
151
+ |`[v0,v1]` |`[[vI],v0,[v1]]` | |
152
+ | |`[[v0],vI,[v1]]` | |
153
+ | |`[[v0],v1,[vI]]` | |
154
+ |`[n0,v1,n2]` |`up([...insert(n0),v1,n2])` |3..5|
155
+ | |`up([n0,v1,...insert(n2)])` |3..5|
156
+ |`[n0,v1,n2,v3,n4]`|`up([...insert(n0),v1,n2,v3,n4])`|5..7|
157
+ | |`up([n0,v1,...insert(n2),v3,n4])`|5..7|
158
+ | |`up([n0,v1,n2,v3,...insert(n4)])`|5..7|
@@ -138,7 +138,7 @@ const seq = require('../list')
138
138
 
139
139
  /**
140
140
  * @template T
141
- * @typedef { readonly [Node<T>, T, Node<T>, T, Node<T>, T, Node<T>] } Branch7
141
+ * @typedef { readonly[...Branch5<T>, T, Node<T>] } Branch7
142
142
  */
143
143
 
144
144
  /** @type {<T>(n: Branch7<T>) => Branch3<T>} */
@@ -346,6 +346,96 @@ const values = node => () => {
346
346
  }
347
347
  }
348
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
+ /**
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
+
349
439
  module.exports = {
350
440
  /** @readonly */
351
441
  values,
@@ -363,5 +453,7 @@ module.exports = {
363
453
  /** @readonly */
364
454
  getOrInsertVisitor: visit(getOrInsertVisitor),
365
455
  /** @readonly */
366
- replaceVisitor: visit(replaceVisitor)
456
+ replaceVisitor: visit(replaceVisitor),
457
+ /** @readonly */
458
+ concat,
367
459
  }
@@ -1,17 +1,105 @@
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
+ const jsonStr = json.stringify(sort)
9
+
10
+ /** @type {(sequence: list.List<json.Unknown>) => string} */
11
+ const stringify = sequence => jsonStr(list.toArray(sequence))
12
+
6
13
  /** @type {(node: btree.Node<string>) => (value: string) => btree.Node<string>} */
7
14
  const set = node => value => {
8
- const result = setVisitor(cmp(value))(node)(() => value)
15
+ const result = setVisitor(stringCmp(value))(node)(() => value)
9
16
  switch (result[0]) {
10
17
  case 'replace': case 'overflow': { return result[1] }
11
18
  default: { return node }
12
19
  }
13
20
  }
14
21
 
22
+ {
23
+ /** @type {btree.Node<string>} */
24
+ let _map = ['a']
25
+ _map = set(_map)('b')
26
+ _map = set(_map)('c')
27
+ _map = set(_map)('d')
28
+ _map = set(_map)('e')
29
+ _map = set(_map)('f')
30
+ let result = stringify(values(_map))
31
+ if (result !== '["a","b","c","d","e","f"]') { throw result }
32
+ }
33
+
34
+ {
35
+ /** @type {btree.Node<string>} */
36
+ let _map = ['1']
37
+ for(let i = 2; i <= 10; i++)
38
+ _map = set(_map)((i*i).toString())
39
+ let result = stringify(values(_map))
40
+ if (result !== '["1","100","16","25","36","4","49","64","81","9"]') { throw result }
41
+ }
42
+
43
+ {
44
+ /** @type {btree.Node<string>} */
45
+ let _map = ['a']
46
+ _map = set(_map)('b')
47
+ _map = set(_map)('c')
48
+ const result = getVisitor(stringCmp('b'))(_map)
49
+ if (result === undefined) { throw result }
50
+ }
51
+
52
+ {
53
+ /** @type {btree.Node<string>} */
54
+ let _map = ['a']
55
+ _map = set(_map)('b')
56
+ _map = set(_map)('c')
57
+ const result = getVisitor(stringCmp('e'))(_map)
58
+ if (result !== undefined) { throw result }
59
+ }
60
+
61
+ {
62
+ /** @type {btree.Node<string>} */
63
+ let _map = ['1']
64
+ for (let i = 2; i <= 10; i++)
65
+ _map = set(_map)((i * i).toString())
66
+ if (_map.length !== 3) { throw _map }
67
+ let _s = jsonStr(_map)
68
+ if (_s !== '[[["1","100"],"16",["25","36"]],"4",[["49"],"64",["81","9"]]]') { throw _s }
69
+
70
+ let [a,,b] = _map
71
+ let _c = concat(a)(b)
72
+ if (_c.length !== 3) { throw _c }
73
+ _s =jsonStr(_c);
74
+ if (_s !== '[[["1","100"],"16",["25"]],"36",[["49"],"64",["81","9"]]]') { throw _s }
75
+
76
+ [a,,b] = _c
77
+ _c = concat(a)(b)
78
+ if (_c.length !== 1) { throw _c }
79
+ _s = jsonStr(_c);
80
+ if (_s !== '[[["1","100"],"16",["25","49"],"64",["81","9"]]]') { throw _s }
81
+
82
+ let [_r] = _c
83
+ if (_r.length !== 5) { throw _r }
84
+ [a,,b] = _r
85
+ _c = concat(a)(b)
86
+ if (_c.length !== 3) { throw _c }
87
+ _s = jsonStr(_c);
88
+ if (_s !== '[["1"],"100",["25","49"]]') { throw _s }
89
+
90
+ [a,,b] = _c
91
+ _c = concat(a)(b)
92
+ if (_c.length !== 3) { throw _c }
93
+ _s = jsonStr(_c);
94
+ if (_s !== '[["1"],"25",["49"]]') { throw _s }
95
+
96
+ [a,,b] = _c
97
+ _c = concat(a)(b)
98
+ if (_c.length !== 1) { throw _c }
99
+ _s = jsonStr(_c);
100
+ if (_s !== '[["1","49"]]') { throw _s }
101
+ }
102
+
15
103
  const test = () => {
16
104
  /** @type {btree.Node<string>} */
17
105
  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 => {