functionalscript 0.0.283 → 0.0.287

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.283",
3
+ "version": "0.0.287",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -54,6 +54,18 @@ const seq = require('../list')
54
54
 
55
55
  /** @typedef {0|1|2|3|4} Index5 */
56
56
 
57
+ /**
58
+ * @template T
59
+ * @typedef {T extends Array1<infer _> ? Index1 :
60
+ * T extends Array2<infer _> ? Index2 :
61
+ * T extends Array3<infer _> ? Index3 :
62
+ * T extends Array4<infer _> ? Index4 :
63
+ * T extends Array5<infer _> ? Index5 :
64
+ * T extends readonly (infer _)[] ? number :
65
+ * never
66
+ * } KeyOf
67
+ */
68
+
57
69
  /** @type {<T>(_: readonly T[]) => readonly T[]} */
58
70
  const uncheckTail = a => a.slice(1)
59
71
 
@@ -0,0 +1,104 @@
1
+ const _ = require('..')
2
+ const list = require('../../list')
3
+ const cmp = require('../../function/compare')
4
+ const array = require('../../array')
5
+
6
+ /**
7
+ * @template T
8
+ * @typedef {readonly[cmp.Index3, _.Leaf1<T>]} FirstLeaf1
9
+ */
10
+
11
+ /**
12
+ * @template T
13
+ * @typedef {readonly[1, _.Branch3<T>]} FirstBranch3
14
+ */
15
+
16
+ /**
17
+ * @template T
18
+ * @typedef {readonly[cmp.Index5, _.Leaf2<T>]} FirstLeaf2
19
+ */
20
+
21
+ /**
22
+ * @template T
23
+ * @typedef {readonly[1|3, _.Branch5<T>]} FirstBranch5
24
+ */
25
+
26
+ /**
27
+ * @template T
28
+ * @typedef {FirstLeaf1<T> | FirstBranch3<T> | FirstLeaf2<T> | FirstBranch5<T>} First
29
+ */
30
+
31
+ /**
32
+ * @template T
33
+ * @typedef {readonly[0|2, _.Branch3<T>]} PathItem3
34
+ */
35
+
36
+ /**
37
+ * @template T
38
+ * @typedef {readonly[0|2|4, _.Branch5<T>]} PathItem5
39
+ */
40
+
41
+ /**
42
+ * @template T
43
+ * @typedef {PathItem3<T> | PathItem5<T>} PathItem
44
+ */
45
+
46
+ /** @type {<T>(item: PathItem<T>) => _.Node<T>} */
47
+ const child = item => {
48
+ /** @typedef {typeof item extends PathItem<infer T> ? T : never} T */
49
+ return /** @type {_.Node<T>} */(item[1][item[0]])
50
+ }
51
+
52
+ /**
53
+ * @template T
54
+ * @typedef {list.List<PathItem<T>>} Path
55
+ */
56
+
57
+ /**
58
+ * @template T
59
+ * @typedef {{
60
+ * readonly first: First<T>,
61
+ * readonly tail: Path<T>
62
+ * }} Result<T>
63
+ */
64
+
65
+ /** @type {<T>(c: cmp.Compare<T>) => (node: _.Node<T>) => Result<T>} */
66
+ const find = c => {
67
+ const i3 = cmp.index3(c)
68
+ const i5 = cmp.index5(c)
69
+ /** @typedef {typeof c extends cmp.Compare<infer T> ? T : never} T */
70
+ /** @type {(prior: Path<T>) => (node: _.Node<T>) => Result<T>} */
71
+ const f = tail => node => {
72
+ /** @type {(index: array.KeyOf<typeof node>) => Result<T>} */
73
+ const append = index => {
74
+ const first = /** @type {PathItem<T>} */([index, node])
75
+ return f({ first, tail })(child(first))
76
+ }
77
+ /** @type {(index: array.KeyOf<typeof node>) => Result<T>} */
78
+ const done = index => ({ first: /** @type {First<T>} */([index, node]), tail })
79
+ switch (node.length) {
80
+ case 1: { return done(i3(node[0])) }
81
+ case 2: { return done(i5(node)) }
82
+ case 3: {
83
+ const i = i3(node[1])
84
+ switch (i) {
85
+ case 0: case 2: { return append(i) }
86
+ case 1: { return done(i) }
87
+ }
88
+ }
89
+ case 5: {
90
+ const i = i5([node[1], node[3]])
91
+ switch (i) {
92
+ case 0: case 2: case 4: { return append(i) }
93
+ case 1: case 3: { return done(i) }
94
+ }
95
+ }
96
+ }
97
+ }
98
+ return f(undefined)
99
+ }
100
+
101
+ module.exports = {
102
+ /** @readonly */
103
+ find,
104
+ }
@@ -0,0 +1,119 @@
1
+ const _ = require('.')
2
+ const list = require('../../list')
3
+ const json = require('../../../json')
4
+ const { sort } = require('../../object')
5
+ const btree = require('..')
6
+ const { stringCmp } = require('../../function/compare')
7
+
8
+ const jsonStr = json.stringify(sort)
9
+
10
+ /** @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
+ }
18
+
19
+ /** @type {(r: _.Result<json.Unknown>) => string} */
20
+ const str = r => jsonStr(list.toArray(list.map(x => x[0])(r)))
21
+
22
+ /** @type {(i: string) => (m: btree.Node<string>) => string} */
23
+ const find = i => m => str(_.find(stringCmp(i))(m))
24
+
25
+ {
26
+ /** @type {btree.Node<string>} */
27
+ let _map = ['1']
28
+ for (let i = 2; i <= 10; i++)
29
+ _map = set(_map)((i * i).toString())
30
+ {
31
+ const s = jsonStr(_map)
32
+ if (s !== '[[["1","100"],"16",["25","36"]],"4",[["49"],"64",["81","9"]]]') { throw s }
33
+ }
34
+ //
35
+ {
36
+ const r = find("0")(_map)
37
+ if (r !== '[0,0,0]') { throw r }
38
+ }
39
+ {
40
+ const r = find("1")(_map)
41
+ if (r !== '[1,0,0]') { throw r }
42
+ }
43
+ {
44
+ const r = find("10")(_map)
45
+ if (r !== '[2,0,0]') { throw r }
46
+ }
47
+ {
48
+ const r = find("100")(_map)
49
+ if (r !== '[3,0,0]') { throw r }
50
+ }
51
+ {
52
+ const r = find("12")(_map)
53
+ if (r !== '[4,0,0]') { throw r }
54
+ }
55
+ {
56
+ const r = find("16")(_map)
57
+ if (r !== '[1,0]') { throw r }
58
+ }
59
+ {
60
+ const r = find("17")(_map)
61
+ if (r !== '[0,2,0]') { throw r }
62
+ }
63
+ {
64
+ const r = find("25")(_map)
65
+ if (r !== '[1,2,0]') { throw r }
66
+ }
67
+ {
68
+ const r = find("26")(_map)
69
+ if (r !== '[2,2,0]') { throw r }
70
+ }
71
+ {
72
+ const r = find("36")(_map)
73
+ if (r !== '[3,2,0]') { throw r }
74
+ }
75
+ {
76
+ const r = find("37")(_map)
77
+ if (r !== '[4,2,0]') { throw r }
78
+ }
79
+ {
80
+ const r = find("4")(_map)
81
+ if (r !== '[1]') { throw r }
82
+ }
83
+ {
84
+ const r = find("41")(_map)
85
+ if (r !== '[0,0,2]') { throw r }
86
+ }
87
+ {
88
+ const r = find("49")(_map)
89
+ if (r !== '[1,0,2]') { throw r }
90
+ }
91
+ {
92
+ const r = find("5")(_map)
93
+ if (r !== '[2,0,2]') { throw r }
94
+ }
95
+ {
96
+ const r = find("64")(_map)
97
+ if (r !== '[1,2]') { throw r }
98
+ }
99
+ {
100
+ const r = find("65")(_map)
101
+ if (r !== '[0,2,2]') { throw r }
102
+ }
103
+ {
104
+ const r = find("81")(_map)
105
+ if (r !== '[1,2,2]') { throw r }
106
+ }
107
+ {
108
+ const r = find("85")(_map)
109
+ if (r !== '[2,2,2]') { throw r }
110
+ }
111
+ {
112
+ const r = find("9")(_map)
113
+ if (r !== '[3,2,2]') { throw r }
114
+ }
115
+ {
116
+ const r = find("91")(_map)
117
+ if (r !== '[4,2,2]') { throw r }
118
+ }
119
+ }
@@ -0,0 +1,39 @@
1
+ const _ = require('..')
2
+ const { find } = require('../find')
3
+ const cmp = require('../../function/compare')
4
+ const { todo } = require('../../../dev')
5
+
6
+ /** @type {<T>(c: cmp.Compare<T>) => (value: T) => (node: _.Node<T>) => _.Node<T>} */
7
+ const set = c => value => node => {
8
+ const { first, tail } = find(c)(node)
9
+ switch (first[0]) {
10
+ case 0: {
11
+ // x2
12
+ const x = first[1]
13
+ return todo()
14
+ }
15
+ case 1: {
16
+ // x4
17
+ const x = first[1];
18
+ return todo()
19
+ }
20
+ case 2: {
21
+ // x2
22
+ const x = first[1];
23
+ return todo()
24
+ }
25
+ case 3: {
26
+ // x2
27
+ const x = first[1];
28
+ return todo()
29
+ }
30
+ case 4: {
31
+ // x1
32
+ const x = first[1];
33
+ return todo()
34
+ }
35
+ }
36
+ return todo()
37
+ }
38
+
39
+ module.exports = {}
@@ -5,6 +5,8 @@ const { sort } = require('../object')
5
5
  const { stringCmp } = require('../function/compare')
6
6
  const list = require('../list')
7
7
 
8
+ require('./find/test')
9
+
8
10
  const jsonStr = json.stringify(sort)
9
11
 
10
12
  /** @type {(sequence: list.List<json.Unknown>) => string} */
@@ -337,6 +337,15 @@ const stress = () => {
337
337
  const len = _.length(_.dropWhile(() => true)(result))
338
338
  if (len !== 0) { throw len }
339
339
  }
340
+
341
+ console.log('reverse')
342
+
343
+ {
344
+ // 10_000_000 is too much
345
+ const n = 5_000_000
346
+ const result = _.toArray(_.reverse(_.countdown(n)))
347
+ if (result.length !== n) { throw result.length }
348
+ }
340
349
  }
341
350
 
342
351
  // stress()