functionalscript 0.0.187 → 0.0.197
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 +15 -18
- package/btree/test.js +10 -10
- package/cmp/index.js +2 -2
- package/function/index.js +0 -5
- package/json/index.js +48 -30
- package/json/test.js +7 -0
- package/map/index.js +20 -8
- package/module-manager/index.js +3 -3
- package/package.json +1 -1
- package/sequence/array/index.js +18 -4
- package/sequence/asyncIterable/index.js +2 -2
- package/sequence/index.js +51 -25
- package/sequence/iterable/index.js +3 -2
- package/sequence/iterable/test.js +3 -3
- package/sequence/test.js +22 -8
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,14 +333,14 @@ 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 }
|
|
343
340
|
*/
|
|
344
341
|
getVisitor: cmp => node => {
|
|
345
|
-
const
|
|
346
|
-
if ('done' in
|
|
342
|
+
const _0 = visit(getVisitor)(cmp)(() => { throw '' })(node)
|
|
343
|
+
if ('done' in _0 && _0.done) { return _0.value }
|
|
347
344
|
return undefined
|
|
348
345
|
},
|
|
349
346
|
/** @readonly */
|
package/btree/test.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const btree = require('.')
|
|
2
|
-
const { setVisitor, valuesList } = btree
|
|
2
|
+
const { setVisitor, values: valuesList } = btree
|
|
3
3
|
const { cmp } = require('../cmp')
|
|
4
4
|
const list = require('../sequence')
|
|
5
5
|
|
|
@@ -13,18 +13,18 @@ const set = node => value => {
|
|
|
13
13
|
|
|
14
14
|
const test = () => {
|
|
15
15
|
/** @type {btree.Node<string>} */
|
|
16
|
-
let
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
let _map = ['a']
|
|
17
|
+
_map = set(_map)('b')
|
|
18
|
+
_map = set(_map)('c')
|
|
19
|
+
_map = set(_map)('d')
|
|
20
|
+
_map = set(_map)('e')
|
|
21
|
+
_map = set(_map)('f')
|
|
22
22
|
//
|
|
23
23
|
{
|
|
24
24
|
/** @type {import('../sequence').Result<string>} */
|
|
25
|
-
let
|
|
26
|
-
while (
|
|
27
|
-
|
|
25
|
+
let _item = list.next(valuesList(_map))
|
|
26
|
+
while (_item !== undefined) {
|
|
27
|
+
_item = list.next(_item[1])
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
}
|
package/cmp/index.js
CHANGED
|
@@ -18,8 +18,8 @@ const index3 = cmp => value => /** @type {Index3} */ (cmp(value) + 1)
|
|
|
18
18
|
|
|
19
19
|
/** @type {<T>(cmp: Cmp<T>) => (v2: Array2<T>) => Index5} */
|
|
20
20
|
const index5 = cmp => ([v0, v1]) => {
|
|
21
|
-
const
|
|
22
|
-
return /** @type {Index5} */ (
|
|
21
|
+
const _0 = cmp(v0)
|
|
22
|
+
return /** @type {Index5} */ (_0 <= 0 ? _0 + 1 : cmp(v1) + 3)
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
/** @type {(a: string) => (b: string) => Sign} */
|
package/function/index.js
CHANGED
|
@@ -7,9 +7,6 @@
|
|
|
7
7
|
/** @type {<X, O>(f: Func<X, O>) => <I>(g: Func<I, X>) => Func<I, O>} */
|
|
8
8
|
const combine = f => g => x => f(g(x))
|
|
9
9
|
|
|
10
|
-
/** @type {<I, X>(g: Func<I, X>) => <O>(g: Func<X, O>) => Func<I, O>} */
|
|
11
|
-
const pipe = g => f => x => f(g(x))
|
|
12
|
-
|
|
13
10
|
/** @type {<T>(value: T) => T} */
|
|
14
11
|
const id = value => value
|
|
15
12
|
|
|
@@ -17,7 +14,5 @@ module.exports = {
|
|
|
17
14
|
/** @readonly */
|
|
18
15
|
id,
|
|
19
16
|
/** @readonly */
|
|
20
|
-
pipe,
|
|
21
|
-
/** @readonly */
|
|
22
17
|
combine,
|
|
23
18
|
}
|
package/json/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
const seq = require('../sequence')
|
|
2
2
|
const map = require('../map')
|
|
3
3
|
const op = require('../sequence/operator')
|
|
4
|
-
const
|
|
4
|
+
const option = require('../option')
|
|
5
|
+
const array = require('../sequence/array')
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* @typedef {{
|
|
@@ -23,62 +24,79 @@ const addProperty = value => {
|
|
|
23
24
|
const [name, tail] = result
|
|
24
25
|
return { ...srcObject, [name]: f(tail)(srcObject[name]) }
|
|
25
26
|
}
|
|
26
|
-
return path => f(
|
|
27
|
+
return path => f(array.sequence(path))
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
/** @type {(kv: readonly[string,
|
|
30
|
-
const property = ([k, v]) =>
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
/** @type {(kv: readonly[string, Json]) => seq.Sequence<string>} */
|
|
31
|
+
const property = ([k, v]) => seq.concat(
|
|
32
|
+
seq.list(JSON.stringify(k)),
|
|
33
|
+
seq.list(':'),
|
|
34
|
+
stringSequence(v))
|
|
35
|
+
|
|
36
|
+
const comma = seq.list(',')
|
|
35
37
|
|
|
36
38
|
/** @type {op.Scan<seq.Sequence<string>, seq.Sequence<string>>} */
|
|
37
|
-
const commaValue = a => [seq.concat(
|
|
39
|
+
const commaValue = a => [seq.concat(comma, a), commaValue]
|
|
38
40
|
|
|
39
41
|
/** @type {op.Scan<seq.Sequence<string>, seq.Sequence<string>>} */
|
|
40
42
|
const joinScan = value => [value, commaValue]
|
|
41
43
|
|
|
42
|
-
/** @type {seq.SequenceMap<seq.Sequence<string>,
|
|
43
|
-
const join =
|
|
44
|
+
/** @type {seq.SequenceMap<seq.Sequence<string>, string>} */
|
|
45
|
+
const join = input => {
|
|
46
|
+
const _0 = seq.scan(joinScan)(input)
|
|
47
|
+
return seq.flat(_0)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** @type {(open: string) => (close: string) => (input: seq.Sequence<seq.Sequence<string>>) => seq.Sequence<string>} */
|
|
51
|
+
const list = open => close => {
|
|
52
|
+
const seqOpen = seq.list(open)
|
|
53
|
+
const seqClose = seq.list(close)
|
|
54
|
+
return input => seq.concat(seqOpen, join(input), seqClose)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const objectList = list('{')('}')
|
|
58
|
+
|
|
59
|
+
const arrayList = list('[')(']')
|
|
44
60
|
|
|
45
61
|
/** @type {(object: Object) => seq.Sequence<string>} */
|
|
46
62
|
const objectStringify = object => {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const result = seq.concat(seq.one('{'))(seq.flat(properties))
|
|
54
|
-
return seq.concat(result)(seq.one('}'))
|
|
63
|
+
const _0 = Object.entries(object)
|
|
64
|
+
const _1 = array.sequence(_0)
|
|
65
|
+
const _2 = map.fromEntries(_1)
|
|
66
|
+
const _3 = _2.entries
|
|
67
|
+
const _4 = seq.map(property)(_3)
|
|
68
|
+
return objectList(_4)
|
|
55
69
|
}
|
|
56
70
|
|
|
57
|
-
/** @type {(
|
|
58
|
-
const arrayStringify =
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
return
|
|
71
|
+
/** @type {(input: Array) => seq.Sequence<string>} */
|
|
72
|
+
const arrayStringify = input => {
|
|
73
|
+
const _0 = array.sequence(input)
|
|
74
|
+
const _1 = seq.map(stringSequence)(_0)
|
|
75
|
+
return arrayList(_1)
|
|
62
76
|
}
|
|
63
77
|
|
|
64
78
|
/** @type {(value: Json) => seq.Sequence<string>} */
|
|
65
|
-
const
|
|
79
|
+
const stringSequence = value => {
|
|
66
80
|
const x = typeof value
|
|
67
81
|
switch (typeof value) {
|
|
68
|
-
case 'boolean': { return seq.
|
|
82
|
+
case 'boolean': { return seq.list(value ? "true" : "false") }
|
|
69
83
|
// Note: we shouldn't use JSON.stringify since it has non determenistic behavior.
|
|
70
84
|
// In particular: property order could be different.
|
|
71
|
-
case 'number': case 'string': { return seq.
|
|
85
|
+
case 'number': case 'string': { return seq.list(JSON.stringify(value)) }
|
|
72
86
|
default: {
|
|
73
|
-
if (value === null) { return seq.
|
|
87
|
+
if (value === null) { return seq.list("null") }
|
|
74
88
|
if (value instanceof Array) { return arrayStringify(value) }
|
|
75
89
|
return objectStringify(value)
|
|
76
90
|
}
|
|
77
91
|
}
|
|
78
92
|
}
|
|
79
93
|
|
|
80
|
-
/**
|
|
81
|
-
|
|
94
|
+
/**
|
|
95
|
+
* A deterministic version of `JSON.stringify`
|
|
96
|
+
*
|
|
97
|
+
* @type {(value: Json) => string}
|
|
98
|
+
*/
|
|
99
|
+
const stringify = value => seq.join('')(stringSequence(value))
|
|
82
100
|
|
|
83
101
|
module.exports = {
|
|
84
102
|
/** @readonly */
|
package/json/test.js
CHANGED
|
@@ -11,3 +11,10 @@ if (json.addProperty("Hello")([])({}) !== "Hello") { throw 'error' }
|
|
|
11
11
|
const x = json.stringify(json.addProperty("Hello")(['a'])({c:[],b:12}))
|
|
12
12
|
if (x !== '{"a":"Hello","b":12,"c":[]}') { throw x }
|
|
13
13
|
}
|
|
14
|
+
|
|
15
|
+
{
|
|
16
|
+
const _0 = { a: { y: [24] }, c: [], b: 12 }
|
|
17
|
+
const _1 = json.addProperty("Hello")(['a', 'x'])(_0)
|
|
18
|
+
const _2 = json.stringify(_1)
|
|
19
|
+
if (_2 !== '{"a":{"x":"Hello","y":[24]},"b":12,"c":[]}') { throw _2 }
|
|
20
|
+
}
|
package/map/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
const option = require("../option")
|
|
2
|
-
const { getVisitor, setVisitor,
|
|
2
|
+
const { getVisitor, setVisitor, values } = 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
|
*/
|
|
@@ -42,12 +43,12 @@ const keyCmp = a => ([b]) => cmp(a)(b)
|
|
|
42
43
|
const create = root => ({
|
|
43
44
|
get: name => option.map(([,value]) => value)(getVisitor(keyCmp(name))(root)),
|
|
44
45
|
set: name => value => {
|
|
45
|
-
const
|
|
46
|
-
if ('replace' in
|
|
47
|
-
if ('overflow' in
|
|
46
|
+
const _0 = setVisitor(keyCmp(name))(() => [name, value])(root)
|
|
47
|
+
if ('replace' in _0) { return create(_0.replace) }
|
|
48
|
+
if ('overflow' in _0) { return create(_0.overflow) }
|
|
48
49
|
throw ''
|
|
49
50
|
},
|
|
50
|
-
entries:
|
|
51
|
+
entries: values(root),
|
|
51
52
|
root,
|
|
52
53
|
})
|
|
53
54
|
|
|
@@ -62,11 +63,22 @@ 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>(map: Map<T>) => (entry: Entry<T>) => Map<T>} */
|
|
71
|
+
const setOperator = map => ([k, v]) => map.set(k)(v)
|
|
72
|
+
|
|
73
|
+
/** @type {<T>(entries: seq.Sequence<Entry<T>>) => Map<T>} */
|
|
74
|
+
const fromEntries = entries => {
|
|
75
|
+
/** @typedef {typeof entries extends seq.Sequence<Entry<infer T>> ? T : never} T */
|
|
76
|
+
return seq.fold(setOperator)(/** @type {Map<T>} */(empty))(entries)
|
|
77
|
+
}
|
|
78
|
+
|
|
69
79
|
module.exports = {
|
|
70
80
|
/** @readonly */
|
|
71
81
|
empty,
|
|
82
|
+
/** @readonly */
|
|
83
|
+
fromEntries,
|
|
72
84
|
}
|
package/module-manager/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const array = require('../sequence/array')
|
|
2
|
-
const {
|
|
2
|
+
const { combine } = require('../function')
|
|
3
3
|
const option = require('../option')
|
|
4
4
|
const { head, last, splitLast, splitFirst } = array
|
|
5
5
|
const iter = require('../sequence/iterable')
|
|
@@ -88,9 +88,9 @@ const external = packages => {
|
|
|
88
88
|
const defined = ([first, tail]) => externalOrInternal(packages(first))(tail)
|
|
89
89
|
/** @type {(_: Path) => readonly [string, Path]|undefined} */
|
|
90
90
|
const sf = splitFirst
|
|
91
|
-
return
|
|
92
|
-
(sf)
|
|
91
|
+
return combine
|
|
93
92
|
(option.map(defined))
|
|
93
|
+
(sf)
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
/** @type {(_: Location) => (_: string) => Module|undefined} */
|
package/package.json
CHANGED
package/sequence/array/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const option = require('../../option')
|
|
2
|
+
const seq = require('..')
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* @template T
|
|
@@ -86,15 +87,26 @@ const head = a => a.length === 0 ? undefined : uncheckHead(a)
|
|
|
86
87
|
|
|
87
88
|
/** @type {<T>(_: Array<T>) => readonly [Array<T>, T]|undefined} */
|
|
88
89
|
const splitLast = a => {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
return option.map(split)(last(a))
|
|
90
|
+
const lastA = last(a)
|
|
91
|
+
if (lastA === undefined) { return undefined }
|
|
92
|
+
return [uncheckHead(a), lastA]
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
/** @type {(index: number) => <T>(a: Array<T>) => readonly[T]|undefined} */
|
|
96
96
|
const at = index => a => index < a.length ? [a[index]] : undefined
|
|
97
97
|
|
|
98
|
+
/** @type {<T>(array: Array<T>) => seq.Sequence<T>} */
|
|
99
|
+
const sequence = a => {
|
|
100
|
+
/** @typedef {typeof a extends Array<infer T> ? T : never} T */
|
|
101
|
+
/** @type {(index: number) => seq.Sequence<T>} */
|
|
102
|
+
const seq = index => () => {
|
|
103
|
+
const result = at(index)(a)
|
|
104
|
+
if (result === undefined) { return undefined }
|
|
105
|
+
return [result[0], seq(index + 1)]
|
|
106
|
+
}
|
|
107
|
+
return seq(0)
|
|
108
|
+
}
|
|
109
|
+
|
|
98
110
|
module.exports = {
|
|
99
111
|
/** @readonly */
|
|
100
112
|
at,
|
|
@@ -110,4 +122,6 @@ module.exports = {
|
|
|
110
122
|
splitFirst,
|
|
111
123
|
/** @readonly */
|
|
112
124
|
splitLast,
|
|
125
|
+
/** @readonly */
|
|
126
|
+
sequence,
|
|
113
127
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const { combine } = require('../../function')
|
|
2
2
|
const seq = require('../operator')
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -69,7 +69,7 @@ const reduce = ([first, s]) => async c => {
|
|
|
69
69
|
|
|
70
70
|
const sum = reduce(seq.sum)
|
|
71
71
|
|
|
72
|
-
const join =
|
|
72
|
+
const join = combine(reduce)(seq.join)
|
|
73
73
|
|
|
74
74
|
const length = reduce(seq.length)
|
|
75
75
|
|
package/sequence/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const array = require('./array')
|
|
2
1
|
const seqOp = require('./operator')
|
|
3
|
-
const {
|
|
2
|
+
const { combine } = require('../function')
|
|
3
|
+
const op = require('../function/operator')
|
|
4
4
|
const { logicalNot, strictEqual } = require('../function/operator')
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -32,7 +32,7 @@ const { logicalNot, strictEqual } = require('../function/operator')
|
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* @template T
|
|
35
|
-
* @typedef {
|
|
35
|
+
* @typedef {readonly[T, Sequence<T>]} FirstAndTail
|
|
36
36
|
*/
|
|
37
37
|
|
|
38
38
|
const empty = () => undefined
|
|
@@ -77,23 +77,43 @@ const first = input => {
|
|
|
77
77
|
* @typedef {(list: Sequence<T>) => R} SequenceReduce
|
|
78
78
|
*/
|
|
79
79
|
|
|
80
|
-
/** @type {<T>(
|
|
81
|
-
const
|
|
80
|
+
/** @type {<T>(...array: readonly T[]) => Sequence<T>} */
|
|
81
|
+
const list = (...array) => {
|
|
82
|
+
/** @typedef {typeof array extends readonly(infer T)[] ? T : never} T */
|
|
83
|
+
let i = array.length
|
|
84
|
+
/** @type {Sequence<T>} */
|
|
85
|
+
let tail = empty
|
|
86
|
+
while (true) {
|
|
87
|
+
if (i === 0) { return tail }
|
|
88
|
+
i = i - 1
|
|
89
|
+
/** @type {FirstAndTail<T>} */
|
|
90
|
+
const result = [array[i], tail]
|
|
91
|
+
tail = () => result
|
|
92
|
+
}
|
|
93
|
+
}
|
|
82
94
|
|
|
83
|
-
/** @type {<T>(array:
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
95
|
+
/** @type {<T>(...array: readonly Sequence<T>[]) => Sequence<T>} */
|
|
96
|
+
const concat = (...array) => {
|
|
97
|
+
let i = array.length
|
|
98
|
+
if (i == 0) { return empty }
|
|
99
|
+
i = i - 1
|
|
100
|
+
let tail = array[i]
|
|
101
|
+
while (true) {
|
|
102
|
+
if (i === 0) { return tail }
|
|
103
|
+
i = i - 1
|
|
104
|
+
tail = [array[i], tail]
|
|
91
105
|
}
|
|
92
|
-
return at(0)
|
|
93
106
|
}
|
|
94
107
|
|
|
95
|
-
/** @type {
|
|
96
|
-
const
|
|
108
|
+
/** @type {(_: number) => Sequence<number>} */
|
|
109
|
+
const generate = n => {
|
|
110
|
+
/** @type {(_: number) => Sequence<number>} */
|
|
111
|
+
const f = i => () => {
|
|
112
|
+
if (n <= i) { return undefined }
|
|
113
|
+
return [i, f(i + 1)]
|
|
114
|
+
}
|
|
115
|
+
return f(0)
|
|
116
|
+
}
|
|
97
117
|
|
|
98
118
|
/** @type {<T, R>(f: (value: T) => Sequence<R>) => SequenceMap<T, R>} */
|
|
99
119
|
const flatMap = f => input => () => {
|
|
@@ -114,16 +134,16 @@ const flatMap = f => input => () => {
|
|
|
114
134
|
const flat = flatMap(i => i)
|
|
115
135
|
|
|
116
136
|
/** @type {<T, R>(f: (value: T) => R) => SequenceMap<T, R>} */
|
|
117
|
-
const map = f => flatMap(i =>
|
|
137
|
+
const map = f => flatMap(i => list(f(i)))
|
|
118
138
|
|
|
119
139
|
/** @type {<T>(f: (value: T) => boolean) => SequenceMap<T, T>} */
|
|
120
|
-
const filter = f => flatMap(i => f(i) ?
|
|
140
|
+
const filter = f => flatMap(i => f(i) ? list(i) : empty)
|
|
121
141
|
|
|
122
142
|
/** @type {<T, R>(f: (value: T) => R|undefined) => (value: T) => Sequence<R>} */
|
|
123
143
|
const filterMapFunc = f => i => {
|
|
124
144
|
const result = f(i)
|
|
125
145
|
if (result === undefined) { return empty }
|
|
126
|
-
return
|
|
146
|
+
return list(result)
|
|
127
147
|
}
|
|
128
148
|
|
|
129
149
|
/** @type {<T, R>(f: (value: T) => R|undefined) => SequenceMap<T, R>} */
|
|
@@ -160,13 +180,17 @@ const last = def => input => {
|
|
|
160
180
|
/** @type {<T, R>(s: seqOp.ExclusiveScan<T, R>) => (input: Sequence<T>) => R} */
|
|
161
181
|
const reduce = ([first, s]) => input => last(first)(scan(s)(input))
|
|
162
182
|
|
|
183
|
+
/** @type {<T, R>(ro: op.ReduceOperator<R, T>) => (first: R) => (input: Sequence<T>) => R} */
|
|
184
|
+
const fold = ro => first => reduce(seqOp.exclusiveScan(ro)(first))
|
|
185
|
+
|
|
163
186
|
const entries = scan(seqOp.entries)
|
|
164
187
|
|
|
165
188
|
const sum = reduce(seqOp.sum)
|
|
166
189
|
|
|
167
190
|
const length = reduce(seqOp.length)
|
|
168
191
|
|
|
169
|
-
|
|
192
|
+
/** @type {(separator: string) => SequenceReduce<string, string>} */
|
|
193
|
+
const join = separator => reduce(seqOp.join(separator))
|
|
170
194
|
|
|
171
195
|
/** @type {<T>(f: (value: T) => boolean) => SequenceMap<T, T>} */
|
|
172
196
|
const takeWhile = f => input => () => {
|
|
@@ -200,7 +224,7 @@ const some = f => input => find(x => x)(map(f)(input)) !== undefined
|
|
|
200
224
|
const includes = value => some(strictEqual(value))
|
|
201
225
|
|
|
202
226
|
/** @type {<T>(f: (value: T) => boolean) => SequenceReduce<T, boolean>} */
|
|
203
|
-
const every = f => input => !some(
|
|
227
|
+
const every = f => input => !some(combine(logicalNot)(f))(input)
|
|
204
228
|
|
|
205
229
|
/** @type {<T>(list: Sequence<T>) => Iterable<T>} */
|
|
206
230
|
const iterable = list => ({
|
|
@@ -228,7 +252,7 @@ const asyncIterable = list => ({
|
|
|
228
252
|
}
|
|
229
253
|
})
|
|
230
254
|
|
|
231
|
-
/** @type {<A>(a: Sequence<A>) => <B>(b: Sequence<B>) => Sequence<
|
|
255
|
+
/** @type {<A>(a: Sequence<A>) => <B>(b: Sequence<B>) => Sequence<readonly[A, B]>} */
|
|
232
256
|
const zip = a => b => () => {
|
|
233
257
|
const resultA = next(a)
|
|
234
258
|
if (resultA === undefined) { return undefined }
|
|
@@ -244,7 +268,7 @@ module.exports = {
|
|
|
244
268
|
/** @readonly */
|
|
245
269
|
next,
|
|
246
270
|
/** @readonly */
|
|
247
|
-
|
|
271
|
+
list,
|
|
248
272
|
/** @readonly */
|
|
249
273
|
empty,
|
|
250
274
|
/** @readonly */
|
|
@@ -252,9 +276,9 @@ module.exports = {
|
|
|
252
276
|
/** @readonly */
|
|
253
277
|
concat,
|
|
254
278
|
/** @readonly */
|
|
255
|
-
|
|
279
|
+
generate,
|
|
256
280
|
/** @readonly */
|
|
257
|
-
|
|
281
|
+
first,
|
|
258
282
|
/** @readonly */
|
|
259
283
|
toArray,
|
|
260
284
|
/** @readonly */
|
|
@@ -278,6 +302,8 @@ module.exports = {
|
|
|
278
302
|
/** @readonly */
|
|
279
303
|
last,
|
|
280
304
|
/** @readonly */
|
|
305
|
+
fold,
|
|
306
|
+
/** @readonly */
|
|
281
307
|
reduce,
|
|
282
308
|
/** @readonly */
|
|
283
309
|
entries,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const { iterable } = require('..')
|
|
2
|
+
const { combine } = require('../../function')
|
|
2
3
|
const seq = require('../operator')
|
|
3
4
|
|
|
4
5
|
/** @type {<T>(a: Iterable<T>) => (b: Iterable<T>) => Iterable<T>} */
|
|
@@ -39,7 +40,7 @@ const sum = reduce(seq.sum)
|
|
|
39
40
|
|
|
40
41
|
const length = reduce(seq.length)
|
|
41
42
|
|
|
42
|
-
const join =
|
|
43
|
+
const join = combine(reduce)(seq.join)
|
|
43
44
|
|
|
44
45
|
/** @type {<T, R>(f: (value: T) => Iterable<R>) => (c: Iterable<T>) => Iterable<R>} */
|
|
45
46
|
const flatMap = f => c => ({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const i = require('.')
|
|
2
|
-
const {
|
|
2
|
+
const { combine } = require('../../function')
|
|
3
3
|
|
|
4
4
|
{
|
|
5
5
|
const r = i.sum([120, 300, 42])
|
|
@@ -33,9 +33,9 @@ const { pipe } = require('../../function')
|
|
|
33
33
|
/** @type {(_: string) => string|undefined} */
|
|
34
34
|
const file = _ => 'x'
|
|
35
35
|
/** @type {(_: string) => string|undefined} */
|
|
36
|
-
const x = p =>
|
|
37
|
-
(i.map(x => file(x())))
|
|
36
|
+
const x = p => combine
|
|
38
37
|
(i.find(x => x !== undefined))
|
|
38
|
+
(i.map(x => file(x())))
|
|
39
39
|
([() => p, () => `${p}.js`, () => `${p}/index.js`])
|
|
40
40
|
if (x('index.js') !== 'x') { throw 'error' }
|
|
41
41
|
}
|
package/sequence/test.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const seq = require('.')
|
|
2
2
|
const { sum } = require('./operator')
|
|
3
3
|
const op = require('./operator')
|
|
4
|
+
const array = require('./array')
|
|
4
5
|
|
|
5
6
|
/** @type {<T>(input: seq.Sequence<T>) => void} */
|
|
6
7
|
const print = input => {
|
|
@@ -8,16 +9,16 @@ const print = input => {
|
|
|
8
9
|
while (true) {
|
|
9
10
|
const result = seq.next(i)
|
|
10
11
|
if (result === undefined) { return }
|
|
11
|
-
|
|
12
|
+
console.log(result[0])
|
|
12
13
|
i = result[1]
|
|
13
14
|
}
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
{
|
|
17
|
-
const big = seq.
|
|
18
|
-
const list0 = seq.
|
|
19
|
-
const list1 = seq.flatMap(x => seq.
|
|
20
|
-
const list2 = seq.concat(list0
|
|
18
|
+
const big = seq.list(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 42, 60)
|
|
19
|
+
const list0 = seq.list(0, 1, 2, 3)
|
|
20
|
+
const list1 = seq.flatMap(x => seq.list(x, x * 2, x * 3))(list0)
|
|
21
|
+
const list2 = seq.concat(list0, list0)
|
|
21
22
|
const list3 = seq.exclusiveScan(sum)(list0)
|
|
22
23
|
const r = seq.find(x => x === 42)(big)
|
|
23
24
|
if (seq.every(x => x > 0)(big) !== true) { throw 'x'}
|
|
@@ -25,10 +26,23 @@ const print = input => {
|
|
|
25
26
|
if (seq.some(x => x > 100)(big) !== false) { throw 'x' }
|
|
26
27
|
if (seq.some(x => x > 50)(big) !== true) { throw 'x' }
|
|
27
28
|
if (seq.first(seq.drop(16)(big)) !== 42) { throw 'drop'}
|
|
29
|
+
{
|
|
30
|
+
const a = seq.toArray(seq.generate(1_000_000))
|
|
31
|
+
let x = seq.concat(array.sequence(a), big)
|
|
32
|
+
const r = seq.next(x)
|
|
33
|
+
// print(x)
|
|
34
|
+
}
|
|
35
|
+
{
|
|
36
|
+
const a = seq.map(seq.generate)(seq.generate(100_000))
|
|
37
|
+
const array = seq.toArray(a)
|
|
38
|
+
const x = seq.concat(...array)
|
|
39
|
+
const r = seq.next(x)
|
|
40
|
+
// print(x)
|
|
41
|
+
}
|
|
28
42
|
{
|
|
29
43
|
let x = big
|
|
30
44
|
for (let i = 0; i < 1_000_000; ++i) {
|
|
31
|
-
x = seq.concat(seq.empty
|
|
45
|
+
x = seq.concat(seq.empty, x)
|
|
32
46
|
}
|
|
33
47
|
const r = seq.next(x)
|
|
34
48
|
// print(x)
|
|
@@ -36,7 +50,7 @@ const print = input => {
|
|
|
36
50
|
{
|
|
37
51
|
let x = big
|
|
38
52
|
for (let i = 0; i < 1_000_000; ++i) {
|
|
39
|
-
x = seq.concat(x
|
|
53
|
+
x = seq.concat(x, seq.list(i))
|
|
40
54
|
}
|
|
41
55
|
const r = seq.next(x)
|
|
42
56
|
// print(x)
|
|
@@ -44,6 +58,6 @@ const print = input => {
|
|
|
44
58
|
}
|
|
45
59
|
|
|
46
60
|
{
|
|
47
|
-
const x = seq.join(':')(seq.
|
|
61
|
+
const x = seq.join(':')(seq.list("1", "2", "3", "4", "5", "6"))
|
|
48
62
|
if (x !== "1:2:3:4:5:6") { throw x }
|
|
49
63
|
}
|