functionalscript 0.0.229 → 0.0.233
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/commonjs/index.js +11 -0
- package/commonjs/package/index.js +72 -0
- package/commonjs/package/test.js +33 -0
- package/commonjs/path/index.js +66 -0
- package/commonjs/path/test.js +47 -0
- package/commonjs/run/index.js +17 -0
- package/io/commonjs/index.js +28 -0
- package/io/commonjs/test.js +72 -0
- package/io/result/index.js +15 -0
- package/json/index.js +29 -29
- package/json/test.js +9 -9
- package/package.json +23 -23
- package/test.js +5 -6
- package/{sequence → types}/array/index.js +2 -2
- package/{btree → types/btree}/README.md +0 -0
- package/{btree → types/btree}/index.js +6 -6
- package/{btree → types/btree}/test.js +1 -1
- package/{cmp → types/function/compare}/index.js +6 -6
- package/{function → types/function}/index.js +0 -0
- package/{function → types/function}/operator/index.js +15 -0
- package/{map → types/map}/index.js +3 -3
- package/{map → types/map}/test.js +0 -0
- package/{object → types/object}/index.js +1 -2
- package/{object → types/object}/test.js +0 -0
- package/{option → types/option}/index.js +0 -0
- package/types/result/index.js +36 -0
- package/{sequence → types/sequence}/README.md +0 -0
- package/{sequence → types/sequence}/index.js +99 -50
- package/{sequence → types/sequence}/test.js +138 -11
- package/version.js +2 -2
- package/module-manager/README.md +0 -35
- package/module-manager/index.js +0 -110
- package/module-manager/node/index.js +0 -18
- package/module-manager/node/test.js +0 -75
- package/module-manager/test.js +0 -120
- package/result/index.js +0 -17
- package/sequence/asyncIterable/index.js +0 -111
- package/sequence/asyncIterable/test.js +0 -24
- package/sequence/iterable/index.js +0 -109
- package/sequence/iterable/test.js +0 -51
- package/sequence/operator/index.js +0 -92
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const btree = require('.')
|
|
2
2
|
const { setVisitor, values } = btree
|
|
3
|
-
const { cmp } = require('../
|
|
3
|
+
const { cmp } = require('../function/compare')
|
|
4
4
|
const list = require('../sequence')
|
|
5
5
|
|
|
6
6
|
/** @type {(node: btree.Node<string>) => (value: string) => btree.Node<string>} */
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
/** @typedef {import('
|
|
2
|
-
/** @typedef {import('
|
|
1
|
+
/** @typedef {import('../../array').Index3} Index3 */
|
|
2
|
+
/** @typedef {import('../../array').Index5} Index5 */
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @template T
|
|
6
|
-
* @typedef {import('
|
|
6
|
+
* @typedef {import('../../array').Array2<T>} Array2
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
/** @typedef {-1|0|1} Sign */
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* @template T
|
|
13
|
-
* @typedef {(_: T) => Sign}
|
|
13
|
+
* @typedef {(_: T) => Sign} Compare
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
/** @type {<T>(cmp:
|
|
16
|
+
/** @type {<T>(cmp: Compare<T>) => (value: T) => Index3} */
|
|
17
17
|
const index3 = cmp => value => /** @type {Index3} */ (cmp(value) + 1)
|
|
18
18
|
|
|
19
|
-
/** @type {<T>(cmp:
|
|
19
|
+
/** @type {<T>(cmp: Compare<T>) => (v2: Array2<T>) => Index5} */
|
|
20
20
|
const index5 = cmp => ([v0, v1]) => {
|
|
21
21
|
const _0 = cmp(v0)
|
|
22
22
|
return /** @type {Index5} */ (_0 <= 0 ? _0 + 1 : cmp(v1) + 3)
|
|
File without changes
|
|
@@ -26,9 +26,20 @@ const addition = a => b => a + b
|
|
|
26
26
|
/** @type {(value: boolean) => boolean} */
|
|
27
27
|
const logicalNot = v => !v
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* @template T
|
|
31
|
+
* @typedef {(a: T) => (b: T) => boolean} EqualOperator
|
|
32
|
+
*/
|
|
33
|
+
|
|
29
34
|
/** @type {<T>(a: T) => (b: T) => boolean} */
|
|
30
35
|
const strictEqual = a => b => a === b
|
|
31
36
|
|
|
37
|
+
/** @type {ReduceOperator<number, number>} */
|
|
38
|
+
const min = a => b => a < b ? a : b
|
|
39
|
+
|
|
40
|
+
/** @type {ReduceOperator<number, number>} */
|
|
41
|
+
const max = a => b => a > b ? a : b
|
|
42
|
+
|
|
32
43
|
module.exports = {
|
|
33
44
|
/** @readonly */
|
|
34
45
|
join,
|
|
@@ -38,4 +49,8 @@ module.exports = {
|
|
|
38
49
|
strictEqual,
|
|
39
50
|
/** @readonly */
|
|
40
51
|
logicalNot,
|
|
52
|
+
/** @readonly */
|
|
53
|
+
min,
|
|
54
|
+
/** @readonly */
|
|
55
|
+
max,
|
|
41
56
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const option = require("../option")
|
|
2
2
|
const { getVisitor, setVisitor, values } = require("../btree")
|
|
3
|
-
const { cmp } = require("../
|
|
3
|
+
const { cmp } = require("../function/compare")
|
|
4
4
|
const seq = require("../sequence")
|
|
5
5
|
|
|
6
|
-
/** @typedef {import("../
|
|
6
|
+
/** @typedef {import("../function/compare").Sign} Sign */
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @template T
|
|
@@ -17,7 +17,7 @@ const seq = require("../sequence")
|
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* @template T
|
|
20
|
-
* @typedef {import("../
|
|
20
|
+
* @typedef {import("../function/compare").Compare<T>} Cmp
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
/**
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @template T
|
|
3
|
+
* @typedef {readonly['ok', T]} Ok
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @template E
|
|
8
|
+
* @typedef {readonly['error', E]} Error
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @template T
|
|
13
|
+
* @template E
|
|
14
|
+
* @typedef {Ok<T>|Error<E>} Result
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** @type {<T>(value: T) => Ok<T>} */
|
|
18
|
+
const ok = value => ['ok', value]
|
|
19
|
+
|
|
20
|
+
/** @type {<E>(e: E) => Error<E>} */
|
|
21
|
+
const error = e => ['error', e]
|
|
22
|
+
|
|
23
|
+
/** @type {<T, E>(r: Result<T, E>) => T} */
|
|
24
|
+
const unwrap = result => {
|
|
25
|
+
if (result[0] === 'error') { throw result[1] }
|
|
26
|
+
return result[1]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = {
|
|
30
|
+
/** @readonly */
|
|
31
|
+
ok,
|
|
32
|
+
/** @readonly */
|
|
33
|
+
error,
|
|
34
|
+
/** @readonly */
|
|
35
|
+
unwrap,
|
|
36
|
+
}
|
|
File without changes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { compose } = require('../function')
|
|
1
|
+
const { compose, identity } = require('../function')
|
|
2
2
|
const { logicalNot, strictEqual, addition } = require('../function/operator')
|
|
3
3
|
const op = require('../function/operator')
|
|
4
4
|
|
|
@@ -19,7 +19,7 @@ const op = require('../function/operator')
|
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* @template T
|
|
22
|
-
* @typedef { readonly[Sequence<T>, Sequence<T>]} Concat<T>
|
|
22
|
+
* @typedef { readonly[Sequence<T>, Sequence<T>] } Concat<T>
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
/**
|
|
@@ -35,7 +35,7 @@ const op = require('../function/operator')
|
|
|
35
35
|
const empty = () => undefined
|
|
36
36
|
|
|
37
37
|
/** @type {<T>(first: T) => (tail: Sequence<T>) => Sequence<T>} */
|
|
38
|
-
const
|
|
38
|
+
const sequence = first => tail => () => ({ first, tail })
|
|
39
39
|
|
|
40
40
|
/** @type {<T>(sequence: Sequence<T>) => Node<T>} */
|
|
41
41
|
const nodeOne = sequence => [empty, sequence]
|
|
@@ -54,6 +54,9 @@ const fromArray = array => {
|
|
|
54
54
|
/** @type {<T>(sequence: Sequence<T>) => Node<T>} */
|
|
55
55
|
const node = sequence => sequence instanceof Array ? fromArray(sequence) : sequence()
|
|
56
56
|
|
|
57
|
+
/** @type {<T>(a: Sequence<T>) => (b: Sequence<T>) => Thunk<T>} */
|
|
58
|
+
const concat = a => b => () => [a, b]
|
|
59
|
+
|
|
57
60
|
/** @type {<T>(sequence: Sequence<T>) => Result<T>} */
|
|
58
61
|
const next = sequence => {
|
|
59
62
|
let i = sequence
|
|
@@ -61,15 +64,15 @@ const next = sequence => {
|
|
|
61
64
|
const n = node(i)
|
|
62
65
|
if (!(n instanceof Array)) { return n }
|
|
63
66
|
const [a, b] = n
|
|
64
|
-
const
|
|
65
|
-
if (
|
|
67
|
+
const aNode = node(a)
|
|
68
|
+
if (aNode === undefined) {
|
|
66
69
|
i = b
|
|
67
|
-
} else if (
|
|
68
|
-
const [aa, ab] =
|
|
69
|
-
i = ()
|
|
70
|
+
} else if (aNode instanceof Array) {
|
|
71
|
+
const [aa, ab] = aNode
|
|
72
|
+
i = concat(aa)(concat(ab)(b))
|
|
70
73
|
} else {
|
|
71
|
-
const { first, tail } =
|
|
72
|
-
return { first, tail: ()
|
|
74
|
+
const { first, tail } = aNode
|
|
75
|
+
return { first, tail: concat(tail)(b) }
|
|
73
76
|
}
|
|
74
77
|
}
|
|
75
78
|
}
|
|
@@ -79,7 +82,6 @@ const iterable = sequence => ({
|
|
|
79
82
|
*[Symbol.iterator]() {
|
|
80
83
|
let i = sequence
|
|
81
84
|
while (true) {
|
|
82
|
-
if (i instanceof Array) { return yield *i }
|
|
83
85
|
const n = next(i)
|
|
84
86
|
if (n === undefined) { return }
|
|
85
87
|
const { first, tail } = n
|
|
@@ -95,64 +97,73 @@ const toArray = sequence => {
|
|
|
95
97
|
return Array.from(iterable(sequence))
|
|
96
98
|
}
|
|
97
99
|
|
|
98
|
-
/** @type {<I, O>(
|
|
99
|
-
const
|
|
100
|
+
/** @type {<I, O>(step: (result: ResultOne<I>) => Node<O>) => (input: Sequence<I>) => Thunk<O>} */
|
|
101
|
+
const apply = f => input => () => {
|
|
100
102
|
const n = next(input)
|
|
101
103
|
if (n === undefined) { return undefined }
|
|
102
104
|
return f(n)
|
|
103
105
|
}
|
|
104
106
|
|
|
105
107
|
/** @type {<T>(result: ResultOne<Sequence<T>>) => Node<T>} */
|
|
106
|
-
const
|
|
108
|
+
const flatStep = ({first, tail}) => [first, flat(tail)]
|
|
107
109
|
|
|
108
110
|
/** @type {<T>(sequence: Sequence<Sequence<T>>) => Thunk<T>} */
|
|
109
|
-
const flat =
|
|
110
|
-
|
|
111
|
-
/** @type {<T>(...array: readonly Sequence<T>[]) => Thunk<T>} */
|
|
112
|
-
const concat = (...array) => flat(array)
|
|
111
|
+
const flat = apply(flatStep)
|
|
113
112
|
|
|
114
113
|
/** @type {<I, O>(f: (value: I) => O) => (result: ResultOne<I>) => Node<O>} */
|
|
115
|
-
const
|
|
114
|
+
const mapStep = f => ({ first, tail }) => ({ first: f(first), tail: map(f)(tail) })
|
|
116
115
|
|
|
117
116
|
/** @type {<I, O>(f: (value: I) => O) => (input: Sequence<I>) => Thunk<O>} */
|
|
118
|
-
const map = f =>
|
|
117
|
+
const map = f => apply(mapStep(f))
|
|
119
118
|
|
|
120
119
|
/** @type {<I, O>(f: (value: I) => Sequence<O>) => (input: Sequence<I>) => Thunk<O>} */
|
|
121
120
|
const flatMap = f => compose(map(f))(flat)
|
|
122
121
|
|
|
123
122
|
/** @type {<T>(f: (value: T) => boolean) => (result: ResultOne<T>) => Node<T>} */
|
|
124
|
-
const
|
|
123
|
+
const filterStep = f => ({ first, tail }) => {
|
|
125
124
|
const fTail = filter(f)(tail)
|
|
126
125
|
return f(first) ? { first, tail: fTail } : nodeOne(fTail)
|
|
127
126
|
}
|
|
128
127
|
|
|
129
128
|
/** @type {<T>(f: (value: T) => boolean) => (input: Sequence<T>) => Thunk<T>} */
|
|
130
|
-
const filter = f =>
|
|
129
|
+
const filter = f => apply(filterStep(f))
|
|
131
130
|
|
|
132
131
|
/** @type {<I, O>(f: (value: I) => O|undefined) => (result: ResultOne<I>) => Node<O>} */
|
|
133
|
-
const
|
|
132
|
+
const filterMapStep = f => ({first, tail}) => {
|
|
134
133
|
const fFirst = f(first)
|
|
135
134
|
const fTail = filterMap(f)(tail)
|
|
136
135
|
return fFirst === undefined ? nodeOne(fTail) : { first: fFirst, tail: fTail }
|
|
137
136
|
}
|
|
138
137
|
|
|
139
138
|
/** @type {<I, O>(f: (value: I) => O|undefined) => (input: Sequence<I>) => Thunk<O>} */
|
|
140
|
-
const filterMap = f =>
|
|
139
|
+
const filterMap = f => apply(filterMapStep(f))
|
|
141
140
|
|
|
142
141
|
/** @type {<T>(f: (value: T) => boolean) => (result: ResultOne<T>) => Node<T>} */
|
|
143
|
-
const
|
|
142
|
+
const takeWhileStep = f => ({ first, tail }) => f(first) ? { first, tail: takeWhile(f)(tail) } :undefined
|
|
144
143
|
|
|
145
144
|
/** @type {<T>(f: (value: T) => boolean) => (input: Sequence<T>) => Thunk<T>} */
|
|
146
|
-
const takeWhile = f =>
|
|
145
|
+
const takeWhile = f => apply(takeWhileStep(f))
|
|
146
|
+
|
|
147
|
+
/** @type {(n: number) => <T>(result: ResultOne<T>) => Node<T>} */
|
|
148
|
+
const takeStep = n => ({ first, tail }) => 0 < n ? { first, tail: take(n - 1)(tail) } : undefined
|
|
149
|
+
|
|
150
|
+
/** @type {(n: number) => <T>(result: Sequence<T>) => Sequence<T>} */
|
|
151
|
+
const take = n => apply(takeStep(n))
|
|
147
152
|
|
|
148
153
|
/** @type {<T>(f: (value: T) => boolean) => (result: ResultOne<T>) => Node<T>} */
|
|
149
|
-
const
|
|
154
|
+
const dropWhileStep = f => result => {
|
|
150
155
|
const { first, tail } = result
|
|
151
156
|
return f(first) ? nodeOne(dropWhile(f)(tail)) : result
|
|
152
157
|
}
|
|
153
158
|
|
|
154
159
|
/** @type {<T>(f: (value: T) => boolean) => (input: Sequence<T>) => Thunk<T>} */
|
|
155
|
-
const dropWhile = f =>
|
|
160
|
+
const dropWhile = f => apply(dropWhileStep(f))
|
|
161
|
+
|
|
162
|
+
/** @type {(n: number) => <T>(result: ResultOne<T>) => Node<T>} */
|
|
163
|
+
const dropFn = n => result => 0 < n ? nodeOne(drop(n - 1)(result.tail)) : result
|
|
164
|
+
|
|
165
|
+
/** @type {(n: number) => <T>(result: Sequence<T>) => Sequence<T>} */
|
|
166
|
+
const drop = n => apply(dropFn(n))
|
|
156
167
|
|
|
157
168
|
/** @type {<D>(def: D) => <T>(input: Sequence<T>) => D|T} */
|
|
158
169
|
const first = def => input => {
|
|
@@ -180,14 +191,17 @@ const last = def => input => {
|
|
|
180
191
|
/** @type {<D>(def: D) => <T>(f: (value: T) => boolean) => (sequence: Sequence<T>) => D|T} */
|
|
181
192
|
const find = def => f => input => first(def)(filter(f)(input))
|
|
182
193
|
|
|
183
|
-
/** @type {
|
|
184
|
-
const
|
|
194
|
+
/** @type {(value: boolean) => boolean} */
|
|
195
|
+
const boolIdentity = identity
|
|
196
|
+
|
|
197
|
+
/** @type {(sequence: Sequence<boolean>) => boolean} */
|
|
198
|
+
const some = input => find(false)(boolIdentity)(input)
|
|
185
199
|
|
|
186
|
-
/** @type {
|
|
187
|
-
const every =
|
|
200
|
+
/** @type {(sequence: Sequence<boolean>) => boolean} */
|
|
201
|
+
const every = input => !some(map(logicalNot)(input))
|
|
188
202
|
|
|
189
203
|
/** @type {<T>(value: T) => (sequence: Sequence<T>) => boolean} */
|
|
190
|
-
const includes = value => some(strictEqual(value))
|
|
204
|
+
const includes = value => input => some(map(strictEqual(value))(input))
|
|
191
205
|
|
|
192
206
|
/** @type {(count: number) => Thunk<number>} */
|
|
193
207
|
const countdown = count => () => {
|
|
@@ -198,24 +212,24 @@ const countdown = count => () => {
|
|
|
198
212
|
|
|
199
213
|
/**
|
|
200
214
|
* @template T,A
|
|
201
|
-
* @typedef {(value: T) => ScanState<T, A>}
|
|
215
|
+
* @typedef {(value: T) => ScanState<T, A>} ScanOperator
|
|
202
216
|
*/
|
|
203
217
|
|
|
204
218
|
/**
|
|
205
219
|
* @template T,A
|
|
206
|
-
* @typedef {readonly[A,
|
|
220
|
+
* @typedef {readonly[A, ScanOperator<T, A>]} ScanState
|
|
207
221
|
*/
|
|
208
222
|
|
|
209
|
-
/** @type {<T,A>(operator:
|
|
223
|
+
/** @type {<T,A>(operator: ScanOperator<T, A>) => (result: ResultOne<T>) => Node<A>} */
|
|
210
224
|
const scanFn = operator => ({first, tail}) => {
|
|
211
225
|
const [value, nextOperator] = operator(first)
|
|
212
226
|
return { first: value, tail: scan(nextOperator)(tail) }
|
|
213
227
|
}
|
|
214
228
|
|
|
215
|
-
/** @type {<T,A>(operator:
|
|
216
|
-
const scan = operator =>
|
|
229
|
+
/** @type {<T,A>(operator: ScanOperator<T, A>) => (input: Sequence<T>) => Thunk<A>} */
|
|
230
|
+
const scan = operator => apply(scanFn(operator))
|
|
217
231
|
|
|
218
|
-
/** @type {<T,A>(operator:
|
|
232
|
+
/** @type {<T,A>(operator: ScanOperator<T, A>) => <D>(def: D)=> (input: Sequence<T>) => D|A} */
|
|
219
233
|
const scanReduce = operator => def => input => last(def)(scan(operator)(input))
|
|
220
234
|
|
|
221
235
|
/**
|
|
@@ -224,16 +238,13 @@ const scanReduce = operator => def => input => last(def)(scan(operator)(input))
|
|
|
224
238
|
*/
|
|
225
239
|
|
|
226
240
|
/** @type {<T,A>(operator: ReduceOperator<T, A>) => (init: A) => ScanState<T, A>} */
|
|
227
|
-
const scanState = operator => init => [init,
|
|
241
|
+
const scanState = operator => init => [init, scanOperator(operator)(init)]
|
|
228
242
|
|
|
229
|
-
/** @type {<T,A>(operator: ReduceOperator<T, A>) => (init: A) =>
|
|
230
|
-
const
|
|
231
|
-
const result = operator(init)(value)
|
|
232
|
-
return scanState(operator)(result)
|
|
233
|
-
}
|
|
243
|
+
/** @type {<T,A>(operator: ReduceOperator<T, A>) => (init: A) => ScanOperator<T, A>} */
|
|
244
|
+
const scanOperator = operator => init => value => scanState(operator)(operator(init)(value))
|
|
234
245
|
|
|
235
246
|
/** @type {<T,A>(operator: ReduceOperator<T, A>) => (init: A) => (input: Sequence<T>) => A} */
|
|
236
|
-
const reduce = operator => init => scanReduce(
|
|
247
|
+
const reduce = operator => init => scanReduce(scanOperator(operator)(init))(init)
|
|
237
248
|
|
|
238
249
|
/**
|
|
239
250
|
* @template T
|
|
@@ -245,6 +256,10 @@ const fold = operator => def => scanReduce(scanState(operator))(def)
|
|
|
245
256
|
|
|
246
257
|
const sum = fold(addition)(0)
|
|
247
258
|
|
|
259
|
+
const min = fold(op.min)(undefined)
|
|
260
|
+
|
|
261
|
+
const max = fold(op.max)(undefined)
|
|
262
|
+
|
|
248
263
|
/** @type {(separator: string) => (input: Sequence<string>) => string} */
|
|
249
264
|
const join = separator => fold(op.join(separator))('')
|
|
250
265
|
|
|
@@ -266,14 +281,36 @@ const entryOp = index => value => [[index, value], entryOp(index + 1)]
|
|
|
266
281
|
const entries = scan(entryOp(0))
|
|
267
282
|
|
|
268
283
|
/** @type {<T>(prior: Sequence<T>) => (value: T) => Sequence<T>} */
|
|
269
|
-
const reverseOp = prior => value =>
|
|
284
|
+
const reverseOp = prior => value => sequence(value)(prior)
|
|
270
285
|
|
|
271
286
|
/** @type {<T>(input: Sequence<T>) => Sequence<T>} */
|
|
272
287
|
const reverse = reduce(reverseOp)(empty)
|
|
273
288
|
|
|
289
|
+
/** @type {<A>(a: Sequence<A>) => <B>(b: Sequence<B>) => Thunk<readonly[A, B]>} */
|
|
290
|
+
const zip = a => b => () => {
|
|
291
|
+
const aResult = next(a)
|
|
292
|
+
if (aResult === undefined) { return undefined }
|
|
293
|
+
const bResult = next(b)
|
|
294
|
+
if (bResult === undefined) { return undefined }
|
|
295
|
+
return { first: [aResult.first, bResult.first], tail: zip(aResult.tail)(bResult.tail) }
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/** @type {<T>(e: op.EqualOperator<T>) => (a: Sequence<T>) => (b: Sequence<T>) => Thunk<boolean>} */
|
|
299
|
+
const equalZip = e => a => b => () => {
|
|
300
|
+
const aResult = next(a)
|
|
301
|
+
const bResult = next(b)
|
|
302
|
+
if (aResult === undefined || bResult === undefined) {
|
|
303
|
+
return { first: aResult === bResult, tail: empty }
|
|
304
|
+
}
|
|
305
|
+
return { first: e(aResult.first)(bResult.first), tail: equalZip(e)(aResult.tail)(bResult.tail) }
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/** @type {<T>(e: op.EqualOperator<T>) => (a: Sequence<T>) => (b: Sequence<T>) => boolean} */
|
|
309
|
+
const equal = e => a => b => every(equalZip(e)(a)(b))
|
|
310
|
+
|
|
274
311
|
module.exports = {
|
|
275
312
|
/** @readonly */
|
|
276
|
-
|
|
313
|
+
sequence,
|
|
277
314
|
/** @readonly */
|
|
278
315
|
iterable,
|
|
279
316
|
/** @readonly */
|
|
@@ -307,9 +344,13 @@ module.exports = {
|
|
|
307
344
|
/** @readonly */
|
|
308
345
|
takeWhile,
|
|
309
346
|
/** @readonly */
|
|
347
|
+
take,
|
|
348
|
+
/** @readonly */
|
|
310
349
|
dropWhile,
|
|
311
350
|
/** @readonly */
|
|
312
|
-
|
|
351
|
+
drop,
|
|
352
|
+
/** @readonly */
|
|
353
|
+
scanOperator,
|
|
313
354
|
/** @readonly */
|
|
314
355
|
scanState,
|
|
315
356
|
/** @readonly */
|
|
@@ -321,6 +362,10 @@ module.exports = {
|
|
|
321
362
|
/** @readonly */
|
|
322
363
|
sum,
|
|
323
364
|
/** @readonly */
|
|
365
|
+
min,
|
|
366
|
+
/** @readonly */
|
|
367
|
+
max,
|
|
368
|
+
/** @readonly */
|
|
324
369
|
join,
|
|
325
370
|
/** @readonly */
|
|
326
371
|
entries,
|
|
@@ -329,5 +374,9 @@ module.exports = {
|
|
|
329
374
|
/** @readonly */
|
|
330
375
|
reverse,
|
|
331
376
|
/** @readonly */
|
|
332
|
-
|
|
377
|
+
zip,
|
|
378
|
+
/** @readonly */
|
|
379
|
+
equal,
|
|
380
|
+
/** @readonly */
|
|
381
|
+
countdown,
|
|
333
382
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const _ = require('.')
|
|
2
|
-
const json = require('
|
|
2
|
+
const json = require('../../json')
|
|
3
3
|
const { sort } = require('../object')
|
|
4
|
-
const { addition } = require('../function/operator')
|
|
4
|
+
const { addition, strictEqual } = require('../function/operator')
|
|
5
5
|
|
|
6
|
-
/** @type {(sequence: _.Sequence<json.
|
|
6
|
+
/** @type {(sequence: _.Sequence<json.Unknown>) => string} */
|
|
7
7
|
const stringify = sequence => json.stringify(sort)(_.toArray(sequence))
|
|
8
8
|
|
|
9
9
|
{
|
|
@@ -17,13 +17,15 @@ const stringify = sequence => json.stringify(sort)(_.toArray(sequence))
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
{
|
|
20
|
-
const result = stringify(_.
|
|
20
|
+
const result = stringify(_.flat([[1, 2, 3], [4, 5], [6], [], [7, 8, 9]]))
|
|
21
21
|
if (result !== '[1,2,3,4,5,6,7,8,9]') { throw result }
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
{
|
|
25
|
-
const result = _.concat([1]
|
|
25
|
+
const result = _.concat([1])([2])
|
|
26
26
|
const x = _.next(result)
|
|
27
|
+
if (x === undefined) { throw x }
|
|
28
|
+
if (x.first !== 1) { throw x }
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
{
|
|
@@ -36,6 +38,21 @@ const stringify = sequence => json.stringify(sort)(_.toArray(sequence))
|
|
|
36
38
|
if (result !== '[1,2,3,4,5]') { throw result }
|
|
37
39
|
}
|
|
38
40
|
|
|
41
|
+
{
|
|
42
|
+
const result = stringify(_.take(3)([1, 2, 3, 4, 5, 6, 7, 8, 9]))
|
|
43
|
+
if (result !== '[1,2,3]') { throw result }
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
{
|
|
47
|
+
const result = stringify(_.take(20)([1, 2, 3, 4, 5, 6, 7, 8, 9]))
|
|
48
|
+
if (result !== '[1,2,3,4,5,6,7,8,9]') { throw result }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
{
|
|
52
|
+
const result = stringify(_.take(0)([1, 2, 3, 4, 5, 6, 7, 8, 9]))
|
|
53
|
+
if (result !== '[]') { throw result }
|
|
54
|
+
}
|
|
55
|
+
|
|
39
56
|
{
|
|
40
57
|
const result = _.find(undefined)(x => x % 2 === 0)([1, 2, 3, 4])
|
|
41
58
|
if (result !== 2) { throw result }
|
|
@@ -51,6 +68,21 @@ const stringify = sequence => json.stringify(sort)(_.toArray(sequence))
|
|
|
51
68
|
if (result !== '[10,11]') { throw result }
|
|
52
69
|
}
|
|
53
70
|
|
|
71
|
+
{
|
|
72
|
+
const result = stringify(_.drop(3)([1, 2, 3, 4, 5, 10, 11]))
|
|
73
|
+
if (result !== '[4,5,10,11]') { throw result }
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
{
|
|
77
|
+
const result = stringify(_.drop(0)([1, 2, 3, 4, 5, 10, 11]))
|
|
78
|
+
if (result !== '[1,2,3,4,5,10,11]') { throw result }
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
{
|
|
82
|
+
const result = stringify(_.drop(10)([1, 2, 3, 4, 5, 10, 11]))
|
|
83
|
+
if (result !== '[]') { throw result }
|
|
84
|
+
}
|
|
85
|
+
|
|
54
86
|
{
|
|
55
87
|
const op = _.scanState(addition)
|
|
56
88
|
const result = stringify(_.scan(op)([2, 3, 4, 5]))
|
|
@@ -102,6 +134,81 @@ const stringify = sequence => json.stringify(sort)(_.toArray(sequence))
|
|
|
102
134
|
if (result !== '[5,4,3,2,1]') { throw result }
|
|
103
135
|
}
|
|
104
136
|
|
|
137
|
+
{
|
|
138
|
+
const result = stringify(_.zip([0, 1, 2])(['a', 'b', 'c', 'd']))
|
|
139
|
+
if (result !== '[[0,"a"],[1,"b"],[2,"c"]]') { throw result }
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
{
|
|
143
|
+
const result = stringify(_.zip([0, 1, 2])(['a', 'b']))
|
|
144
|
+
if (result !== '[[0,"a"],[1,"b"]]') { throw result }
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
{
|
|
148
|
+
const result = _.some(_.map(x => x > 5)([0, 1, 7]))
|
|
149
|
+
if (!result) { throw result}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
{
|
|
153
|
+
const result = _.some(_.map(x => x > 5)([0, 1, 4]))
|
|
154
|
+
if (result) { throw result }
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
{
|
|
158
|
+
const result = _.some(_.map(x => x > 5)([]))
|
|
159
|
+
if (result) { throw result }
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
{
|
|
163
|
+
const result = _.every(_.map(x => x > 5)([0, 1, 7]))
|
|
164
|
+
if (result) { throw result }
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
{
|
|
168
|
+
const result = _.every(_.map(x => x > 5)([6, 11, 7]))
|
|
169
|
+
if (!result) { throw result }
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
{
|
|
173
|
+
const result = _.every(_.map(x => x > 5)([]))
|
|
174
|
+
if (!result) { throw result }
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
{
|
|
178
|
+
const result = _.equal(strictEqual)([1])([2, 3])
|
|
179
|
+
if (result) { throw result}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
{
|
|
183
|
+
const result = _.equal(strictEqual)([1, 3])([1])
|
|
184
|
+
if (result) { throw result }
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
{
|
|
188
|
+
const result = _.equal(strictEqual)([15, 78])([15, 78])
|
|
189
|
+
if (!result) { throw result }
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
{
|
|
193
|
+
const result = _.equal(strictEqual)([])([])
|
|
194
|
+
if (!result) { throw result }
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
{
|
|
198
|
+
const result = _.min([])
|
|
199
|
+
if (result !== undefined) { throw result }
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
{
|
|
203
|
+
const result = _.min([1, 2, 12, -4, 8])
|
|
204
|
+
if (result !== -4) { throw result }
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
{
|
|
208
|
+
const result = _.max([1, 2, 12, -4, 8])
|
|
209
|
+
if (result !== 12) { throw result }
|
|
210
|
+
}
|
|
211
|
+
|
|
105
212
|
// stress tests
|
|
106
213
|
|
|
107
214
|
const stress = () => {
|
|
@@ -129,9 +236,19 @@ const stress = () => {
|
|
|
129
236
|
{
|
|
130
237
|
/** @type {_.Sequence<number>} */
|
|
131
238
|
let sequence = []
|
|
132
|
-
//
|
|
133
|
-
for (let i = 0; i <
|
|
134
|
-
sequence = _.concat(sequence
|
|
239
|
+
// 10_000_000 is too much
|
|
240
|
+
for (let i = 0; i < 5_000_000; ++i) {
|
|
241
|
+
sequence = _.concat(sequence)([i])
|
|
242
|
+
}
|
|
243
|
+
const r = _.toArray(sequence)
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
{
|
|
247
|
+
/** @type {_.Sequence<number>} */
|
|
248
|
+
let sequence = []
|
|
249
|
+
// 4_000_000 is too much
|
|
250
|
+
for (let i = 0; i < 2_000_000; ++i) {
|
|
251
|
+
sequence = _.flat([sequence, [i]])
|
|
135
252
|
}
|
|
136
253
|
const r = _.toArray(sequence)
|
|
137
254
|
}
|
|
@@ -141,7 +258,17 @@ const stress = () => {
|
|
|
141
258
|
let sequence = []
|
|
142
259
|
// 5_000_000 is too much
|
|
143
260
|
for (let i = 0; i < 2_000_000; ++i) {
|
|
144
|
-
sequence = _.
|
|
261
|
+
sequence = _.flat([sequence, [i]])
|
|
262
|
+
}
|
|
263
|
+
const a = _.next(sequence)
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
{
|
|
267
|
+
/** @type {_.Sequence<number>} */
|
|
268
|
+
let sequence = []
|
|
269
|
+
// 20_000_000 is too much
|
|
270
|
+
for (let i = 0; i < 10_000_000; ++i) {
|
|
271
|
+
sequence = _.concat([i])(sequence)
|
|
145
272
|
}
|
|
146
273
|
const a = _.next(sequence)
|
|
147
274
|
}
|
|
@@ -151,7 +278,7 @@ const stress = () => {
|
|
|
151
278
|
let sequence = []
|
|
152
279
|
// 10_000_000 is too much
|
|
153
280
|
for (let i = 0; i < 5_000_000; ++i) {
|
|
154
|
-
sequence = _.
|
|
281
|
+
sequence = _.flat([[i], sequence])
|
|
155
282
|
}
|
|
156
283
|
const a = _.next(sequence)
|
|
157
284
|
}
|
|
@@ -183,4 +310,4 @@ const stress = () => {
|
|
|
183
310
|
|
|
184
311
|
module.exports = {
|
|
185
312
|
|
|
186
|
-
}
|
|
313
|
+
}
|