functionalscript 0.0.190 → 0.0.191
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/btree/index.js +13 -16
- package/btree/test.js +1 -1
- package/json/index.js +8 -11
- package/map/index.js +10 -4
- package/package.json +1 -1
- package/sequence/index.js +46 -11
- package/sequence/test.js +16 -5
package/btree/index.js
CHANGED
|
@@ -305,28 +305,25 @@ const replaceVisitor = {
|
|
|
305
305
|
notFound: notFoundGet,
|
|
306
306
|
}
|
|
307
307
|
|
|
308
|
-
/** @type {<T>(...array: readonly seq.Sequence<T>[]) => seq.Sequence<T>} */
|
|
309
|
-
const flatArray = (...array) => seq.flat(seq.fromArray(array))
|
|
310
|
-
|
|
311
308
|
/** @type {<T>(node: Node<T>) => seq.Sequence<T>} */
|
|
312
|
-
const
|
|
309
|
+
const values = node => () => {
|
|
313
310
|
const f = () => {
|
|
314
311
|
switch (node.length) {
|
|
315
|
-
case 1: case 2: { return seq.
|
|
312
|
+
case 1: case 2: { return seq.list(...node) }
|
|
316
313
|
case 3: {
|
|
317
|
-
return
|
|
318
|
-
|
|
319
|
-
seq.
|
|
320
|
-
|
|
314
|
+
return seq.concat(
|
|
315
|
+
values(node[0]),
|
|
316
|
+
seq.list(node[1]),
|
|
317
|
+
values(node[2])
|
|
321
318
|
)
|
|
322
319
|
}
|
|
323
320
|
default: {
|
|
324
|
-
return
|
|
325
|
-
|
|
326
|
-
seq.
|
|
327
|
-
|
|
328
|
-
seq.
|
|
329
|
-
|
|
321
|
+
return seq.concat(
|
|
322
|
+
values(node[0]),
|
|
323
|
+
seq.list(node[1]),
|
|
324
|
+
values(node[2]),
|
|
325
|
+
seq.list(node[3]),
|
|
326
|
+
values(node[4])
|
|
330
327
|
)
|
|
331
328
|
}
|
|
332
329
|
}
|
|
@@ -336,7 +333,7 @@ const valuesList = node => () => {
|
|
|
336
333
|
|
|
337
334
|
module.exports = {
|
|
338
335
|
/** @readonly */
|
|
339
|
-
|
|
336
|
+
values,
|
|
340
337
|
/**
|
|
341
338
|
* @readonly
|
|
342
339
|
* @type { <T>(cmp: Cmp<T>) => (node: Node<T>) => T|undefined }
|
package/btree/test.js
CHANGED
package/json/index.js
CHANGED
|
@@ -26,10 +26,10 @@ const addProperty = value => {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
/** @type {(kv: readonly[string, seq.Sequence<string>]) => seq.Sequence<string>} */
|
|
29
|
-
const property = ([k, v]) => seq.concat(seq.
|
|
29
|
+
const property = ([k, v]) => seq.concat(seq.list(JSON.stringify(k)), seq.list(':'), v)
|
|
30
30
|
|
|
31
31
|
/** @type {op.Scan<seq.Sequence<string>, seq.Sequence<string>>} */
|
|
32
|
-
const commaValue = a => [seq.concat(seq.
|
|
32
|
+
const commaValue = a => [seq.concat(seq.list(','), a), commaValue]
|
|
33
33
|
|
|
34
34
|
/** @type {op.Scan<seq.Sequence<string>, seq.Sequence<string>>} */
|
|
35
35
|
const joinScan = value => [value, commaValue]
|
|
@@ -39,8 +39,8 @@ const join = input => seq.flat(seq.scan(joinScan)(input))
|
|
|
39
39
|
|
|
40
40
|
/** @type {(open: string) => (close: string) => (input: seq.Sequence<seq.Sequence<string>>) => seq.Sequence<string>} */
|
|
41
41
|
const list = open => close => {
|
|
42
|
-
const seqOpen = seq.
|
|
43
|
-
const seqClose = seq.
|
|
42
|
+
const seqOpen = seq.list(open)
|
|
43
|
+
const seqClose = seq.list(close)
|
|
44
44
|
return input => seq.concat(seqOpen, join(input), seqClose)
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -51,10 +51,7 @@ const arrayList = list('[')(']')
|
|
|
51
51
|
/** @type {(object: Object) => seq.Sequence<string>} */
|
|
52
52
|
const objectStringify = object => {
|
|
53
53
|
/** @type {map.Map<seq.Sequence<string>>} */
|
|
54
|
-
|
|
55
|
-
for (const [k, v] of Object.entries(object)) {
|
|
56
|
-
m = m.set(k)(stringSeq(v))
|
|
57
|
-
}
|
|
54
|
+
const m = seq.fold(m => ([k, v]) => m.set(k)(stringSeq(v)))(map.empty)(seq.fromArray(Object.entries(object)))
|
|
58
55
|
return objectList(seq.map(property)(m.entries))
|
|
59
56
|
}
|
|
60
57
|
|
|
@@ -65,12 +62,12 @@ const arrayStringify = array => arrayList(seq.map(stringSeq)(seq.fromArray(array
|
|
|
65
62
|
const stringSeq = value => {
|
|
66
63
|
const x = typeof value
|
|
67
64
|
switch (typeof value) {
|
|
68
|
-
case 'boolean': { return seq.
|
|
65
|
+
case 'boolean': { return seq.list(value ? "true" : "false") }
|
|
69
66
|
// Note: we shouldn't use JSON.stringify since it has non determenistic behavior.
|
|
70
67
|
// In particular: property order could be different.
|
|
71
|
-
case 'number': case 'string': { return seq.
|
|
68
|
+
case 'number': case 'string': { return seq.list(JSON.stringify(value)) }
|
|
72
69
|
default: {
|
|
73
|
-
if (value === null) { return seq.
|
|
70
|
+
if (value === null) { return seq.list("null") }
|
|
74
71
|
if (value instanceof Array) { return arrayStringify(value) }
|
|
75
72
|
return objectStringify(value)
|
|
76
73
|
}
|
package/map/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
const option = require("../option")
|
|
2
|
-
const { getVisitor, setVisitor, valuesList } = require("../btree")
|
|
2
|
+
const { getVisitor, setVisitor, values: valuesList } = require("../btree")
|
|
3
3
|
const { cmp } = require("../cmp")
|
|
4
|
-
const
|
|
4
|
+
const seq = require("../sequence")
|
|
5
|
+
const op = require("../sequence/operator")
|
|
5
6
|
|
|
6
7
|
/** @typedef {import("../cmp").Sign} Sign */
|
|
7
8
|
|
|
@@ -30,7 +31,7 @@ const list = require("../sequence")
|
|
|
30
31
|
* @typedef {{
|
|
31
32
|
* readonly get: (name: string) => T|undefined
|
|
32
33
|
* readonly set: (name: string) => (value: T) => Map<T>
|
|
33
|
-
* readonly entries:
|
|
34
|
+
* readonly entries: seq.Sequence<Entry<T>>
|
|
34
35
|
* readonly root: undefined|TNode<Entry<T>>
|
|
35
36
|
* }} Map
|
|
36
37
|
*/
|
|
@@ -62,11 +63,16 @@ const create = root => ({
|
|
|
62
63
|
const empty = {
|
|
63
64
|
get: () => undefined,
|
|
64
65
|
set: name => value => create([[name, value]]),
|
|
65
|
-
entries:
|
|
66
|
+
entries: seq.empty,
|
|
66
67
|
root: undefined
|
|
67
68
|
}
|
|
68
69
|
|
|
70
|
+
/** @type {<T>(entries: seq.Sequence<Entry<T>>) => Map<T>} */
|
|
71
|
+
const fromEntries = seq.fold(map => entry => map.set(entry))(empty)
|
|
72
|
+
|
|
69
73
|
module.exports = {
|
|
70
74
|
/** @readonly */
|
|
71
75
|
empty,
|
|
76
|
+
/** @readonly */
|
|
77
|
+
fromEntries,
|
|
72
78
|
}
|
package/package.json
CHANGED
package/sequence/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const array = require('./array')
|
|
2
2
|
const seqOp = require('./operator')
|
|
3
3
|
const { pipe } = require('../function')
|
|
4
|
+
const op = require('../function/operator')
|
|
4
5
|
const { logicalNot, strictEqual } = require('../function/operator')
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -77,8 +78,20 @@ const first = input => {
|
|
|
77
78
|
* @typedef {(list: Sequence<T>) => R} SequenceReduce
|
|
78
79
|
*/
|
|
79
80
|
|
|
80
|
-
/** @type {<T>(
|
|
81
|
-
const
|
|
81
|
+
/** @type {<T>(...array: readonly T[]) => Sequence<T>} */
|
|
82
|
+
const list = (...array) => {
|
|
83
|
+
/** @typedef {typeof array extends readonly(infer T)[] ? T : never} T */
|
|
84
|
+
let i = array.length
|
|
85
|
+
/** @type {Sequence<T>} */
|
|
86
|
+
let tail = empty
|
|
87
|
+
while (true) {
|
|
88
|
+
if (i === 0) { return tail }
|
|
89
|
+
i = i - 1
|
|
90
|
+
/** @type {FirstAndTail<T>} */
|
|
91
|
+
const result = [array[i], tail]
|
|
92
|
+
tail = () => result
|
|
93
|
+
}
|
|
94
|
+
}
|
|
82
95
|
|
|
83
96
|
/** @type {<T>(array: array.Array<T>) => Sequence<T>} */
|
|
84
97
|
const fromArray = a => {
|
|
@@ -92,11 +105,28 @@ const fromArray = a => {
|
|
|
92
105
|
return at(0)
|
|
93
106
|
}
|
|
94
107
|
|
|
95
|
-
/** @type {<T>(a: Sequence<T>) => SequenceMap<T, T>} */
|
|
96
|
-
const concat2 = a => b => [a, b]
|
|
97
|
-
|
|
98
108
|
/** @type {<T>(...array: readonly Sequence<T>[]) => Sequence<T>} */
|
|
99
|
-
const concat = (...
|
|
109
|
+
const concat = (...array) => {
|
|
110
|
+
let i = array.length
|
|
111
|
+
if (i == 0) { return empty }
|
|
112
|
+
i = i - 1
|
|
113
|
+
let tail = array[i]
|
|
114
|
+
while (true) {
|
|
115
|
+
if (i === 0) { return tail }
|
|
116
|
+
i = i - 1
|
|
117
|
+
tail = [array[i], tail]
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** @type {(_: number) => Sequence<number>} */
|
|
122
|
+
const generate = n => {
|
|
123
|
+
/** @type {(_: number) => Sequence<number>} */
|
|
124
|
+
const f = i => () => {
|
|
125
|
+
if (n <= i) { return undefined }
|
|
126
|
+
return [i, f(i + 1)]
|
|
127
|
+
}
|
|
128
|
+
return f(0)
|
|
129
|
+
}
|
|
100
130
|
|
|
101
131
|
/** @type {<T, R>(f: (value: T) => Sequence<R>) => SequenceMap<T, R>} */
|
|
102
132
|
const flatMap = f => input => () => {
|
|
@@ -117,16 +147,16 @@ const flatMap = f => input => () => {
|
|
|
117
147
|
const flat = flatMap(i => i)
|
|
118
148
|
|
|
119
149
|
/** @type {<T, R>(f: (value: T) => R) => SequenceMap<T, R>} */
|
|
120
|
-
const map = f => flatMap(i =>
|
|
150
|
+
const map = f => flatMap(i => list(f(i)))
|
|
121
151
|
|
|
122
152
|
/** @type {<T>(f: (value: T) => boolean) => SequenceMap<T, T>} */
|
|
123
|
-
const filter = f => flatMap(i => f(i) ?
|
|
153
|
+
const filter = f => flatMap(i => f(i) ? list(i) : empty)
|
|
124
154
|
|
|
125
155
|
/** @type {<T, R>(f: (value: T) => R|undefined) => (value: T) => Sequence<R>} */
|
|
126
156
|
const filterMapFunc = f => i => {
|
|
127
157
|
const result = f(i)
|
|
128
158
|
if (result === undefined) { return empty }
|
|
129
|
-
return
|
|
159
|
+
return list(result)
|
|
130
160
|
}
|
|
131
161
|
|
|
132
162
|
/** @type {<T, R>(f: (value: T) => R|undefined) => SequenceMap<T, R>} */
|
|
@@ -163,6 +193,9 @@ const last = def => input => {
|
|
|
163
193
|
/** @type {<T, R>(s: seqOp.ExclusiveScan<T, R>) => (input: Sequence<T>) => R} */
|
|
164
194
|
const reduce = ([first, s]) => input => last(first)(scan(s)(input))
|
|
165
195
|
|
|
196
|
+
/** @type {<T, R>(ro: op.ReduceOperator<R, T>) => (first: R) => (input: Sequence<T>) => R} */
|
|
197
|
+
const fold = ro => first => reduce(seqOp.exclusiveScan(ro)(first))
|
|
198
|
+
|
|
166
199
|
const entries = scan(seqOp.entries)
|
|
167
200
|
|
|
168
201
|
const sum = reduce(seqOp.sum)
|
|
@@ -247,7 +280,7 @@ module.exports = {
|
|
|
247
280
|
/** @readonly */
|
|
248
281
|
next,
|
|
249
282
|
/** @readonly */
|
|
250
|
-
|
|
283
|
+
list,
|
|
251
284
|
/** @readonly */
|
|
252
285
|
empty,
|
|
253
286
|
/** @readonly */
|
|
@@ -255,7 +288,7 @@ module.exports = {
|
|
|
255
288
|
/** @readonly */
|
|
256
289
|
concat,
|
|
257
290
|
/** @readonly */
|
|
258
|
-
|
|
291
|
+
generate,
|
|
259
292
|
/** @readonly */
|
|
260
293
|
first,
|
|
261
294
|
/** @readonly */
|
|
@@ -283,6 +316,8 @@ module.exports = {
|
|
|
283
316
|
/** @readonly */
|
|
284
317
|
last,
|
|
285
318
|
/** @readonly */
|
|
319
|
+
fold,
|
|
320
|
+
/** @readonly */
|
|
286
321
|
reduce,
|
|
287
322
|
/** @readonly */
|
|
288
323
|
entries,
|
package/sequence/test.js
CHANGED
|
@@ -8,7 +8,7 @@ const print = input => {
|
|
|
8
8
|
while (true) {
|
|
9
9
|
const result = seq.next(i)
|
|
10
10
|
if (result === undefined) { return }
|
|
11
|
-
|
|
11
|
+
console.log(result[0])
|
|
12
12
|
i = result[1]
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -25,11 +25,23 @@ const print = input => {
|
|
|
25
25
|
if (seq.some(x => x > 100)(big) !== false) { throw 'x' }
|
|
26
26
|
if (seq.some(x => x > 50)(big) !== true) { throw 'x' }
|
|
27
27
|
if (seq.first(seq.drop(16)(big)) !== 42) { throw 'drop'}
|
|
28
|
+
{
|
|
29
|
+
const a = seq.toArray(seq.generate(1_000_000))
|
|
30
|
+
let x = seq.concat(seq.fromArray(a), big)
|
|
31
|
+
const r = seq.next(x)
|
|
32
|
+
// print(x)
|
|
33
|
+
}
|
|
34
|
+
{
|
|
35
|
+
const a = seq.map(seq.generate)(seq.generate(100_000))
|
|
36
|
+
const array = seq.toArray(a)
|
|
37
|
+
const x = seq.concat(...array)
|
|
38
|
+
const r = seq.next(x)
|
|
39
|
+
// print(x)
|
|
40
|
+
}
|
|
28
41
|
{
|
|
29
42
|
let x = big
|
|
30
43
|
for (let i = 0; i < 1_000_000; ++i) {
|
|
31
|
-
|
|
32
|
-
x = seq.concat2(seq.empty)(x)
|
|
44
|
+
x = seq.concat(seq.empty, x)
|
|
33
45
|
}
|
|
34
46
|
const r = seq.next(x)
|
|
35
47
|
// print(x)
|
|
@@ -37,8 +49,7 @@ const print = input => {
|
|
|
37
49
|
{
|
|
38
50
|
let x = big
|
|
39
51
|
for (let i = 0; i < 1_000_000; ++i) {
|
|
40
|
-
|
|
41
|
-
x = seq.concat2(x)(seq.one(i))
|
|
52
|
+
x = seq.concat(x, seq.list(i))
|
|
42
53
|
}
|
|
43
54
|
const r = seq.next(x)
|
|
44
55
|
// print(x)
|