functionalscript 0.0.231 → 0.0.235
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/.github/workflows/npm-publish.yml +1 -1
- package/commonjs/index.js +11 -0
- package/commonjs/package/dependencies/index.js +71 -0
- package/commonjs/package/dependencies/test.js +33 -0
- package/commonjs/package/index.js +37 -0
- package/commonjs/package/test.js +14 -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/nodejs/version/index.js +20 -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 +6 -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 +83 -36
- package/{sequence → types/sequence}/test.js +138 -11
- 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
- package/version.js +0 -17
package/package.json
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
2
|
+
"name": "functionalscript",
|
|
3
|
+
"version": "0.0.235",
|
|
4
|
+
"description": "FunctionalScript is a functional subset of JavaScript",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"tsc": "tsc",
|
|
8
|
+
"test": "tsc && npm run test-only",
|
|
9
|
+
"test-only": "node --trace-uncaught ./test"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/functionalscript/functionalscript.git"
|
|
14
|
+
},
|
|
15
|
+
"author": "Natfoam",
|
|
16
|
+
"license": "Apache-2.0",
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/functionalscript/functionalscript/issues"
|
|
19
|
+
},
|
|
20
|
+
"homepage": "https://github.com/functionalscript/functionalscript#readme",
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/node": "^16.11.11",
|
|
23
|
+
"typescript": "^4.5.2"
|
|
24
|
+
}
|
|
25
25
|
}
|
package/test.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
const i = require('./')
|
|
2
2
|
|
|
3
|
-
require('./sequence/test')
|
|
4
|
-
require('./btree/test')
|
|
5
|
-
require('./sequence/iterable/test')
|
|
6
|
-
require('./sequence/asyncIterable/test')
|
|
7
|
-
require('./module-manager/test')
|
|
3
|
+
require('./types/sequence/test')
|
|
4
|
+
require('./types/btree/test')
|
|
8
5
|
require('./json/test')
|
|
9
|
-
require('./object/test')
|
|
6
|
+
require('./types/object/test')
|
|
7
|
+
require('./io/commonjs/test')
|
|
8
|
+
require('./commonjs/package/dependencies/test')
|
|
9
|
+
require('./commonjs/package/test')
|
|
10
10
|
|
|
11
11
|
/** @type {() => never} */
|
|
12
12
|
const assert = () => { throw 'assert' }
|
|
File without changes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const cmp = require('../
|
|
1
|
+
const cmp = require('../function/compare')
|
|
2
2
|
const { index3, index5 } = cmp
|
|
3
3
|
const seq = require('../sequence')
|
|
4
4
|
|
|
@@ -9,7 +9,7 @@ const seq = require('../sequence')
|
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* @template T
|
|
12
|
-
* @typedef {cmp.
|
|
12
|
+
* @typedef {cmp.Compare<T>} Cmp
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -311,20 +311,20 @@ const values = node => () => {
|
|
|
311
311
|
switch (node.length) {
|
|
312
312
|
case 1: case 2: { return node }
|
|
313
313
|
case 3: {
|
|
314
|
-
return seq.
|
|
314
|
+
return seq.flat([
|
|
315
315
|
values(node[0]),
|
|
316
316
|
[node[1]],
|
|
317
317
|
values(node[2])
|
|
318
|
-
)
|
|
318
|
+
])
|
|
319
319
|
}
|
|
320
320
|
default: {
|
|
321
|
-
return seq.
|
|
321
|
+
return seq.flat([
|
|
322
322
|
values(node[0]),
|
|
323
323
|
[node[1]],
|
|
324
324
|
values(node[2]),
|
|
325
325
|
[node[3]],
|
|
326
326
|
values(node[4])
|
|
327
|
-
)
|
|
327
|
+
])
|
|
328
328
|
}
|
|
329
329
|
}
|
|
330
330
|
}
|
|
@@ -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
|
/**
|
|
@@ -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
|
|
@@ -66,10 +69,10 @@ const next = sequence => {
|
|
|
66
69
|
i = b
|
|
67
70
|
} else if (aNode instanceof Array) {
|
|
68
71
|
const [aa, ab] = aNode
|
|
69
|
-
i = ()
|
|
72
|
+
i = concat(aa)(concat(ab)(b))
|
|
70
73
|
} else {
|
|
71
74
|
const { first, tail } = aNode
|
|
72
|
-
return { first, tail: ()
|
|
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
|
|
185
196
|
|
|
186
|
-
/** @type {
|
|
187
|
-
const
|
|
197
|
+
/** @type {(sequence: Sequence<boolean>) => boolean} */
|
|
198
|
+
const some = input => find(false)(boolIdentity)(input)
|
|
199
|
+
|
|
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 => () => {
|
|
@@ -213,7 +227,7 @@ const scanFn = operator => ({first, tail}) => {
|
|
|
213
227
|
}
|
|
214
228
|
|
|
215
229
|
/** @type {<T,A>(operator: ScanOperator<T, A>) => (input: Sequence<T>) => Thunk<A>} */
|
|
216
|
-
const scan = operator =>
|
|
230
|
+
const scan = operator => apply(scanFn(operator))
|
|
217
231
|
|
|
218
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))
|
|
@@ -227,10 +241,7 @@ const scanReduce = operator => def => input => last(def)(scan(operator)(input))
|
|
|
227
241
|
const scanState = operator => init => [init, scanOperator(operator)(init)]
|
|
228
242
|
|
|
229
243
|
/** @type {<T,A>(operator: ReduceOperator<T, A>) => (init: A) => ScanOperator<T, A>} */
|
|
230
|
-
const scanOperator = operator => init => value =>
|
|
231
|
-
const result = operator(init)(value)
|
|
232
|
-
return scanState(operator)(result)
|
|
233
|
-
}
|
|
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
247
|
const reduce = operator => init => scanReduce(scanOperator(operator)(init))(init)
|
|
@@ -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
|
|
|
@@ -271,9 +286,29 @@ const reverseOp = prior => value => sequence(value)(prior)
|
|
|
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
|
-
/** @readonly */
|
|
276
|
-
empty,
|
|
277
312
|
/** @readonly */
|
|
278
313
|
sequence,
|
|
279
314
|
/** @readonly */
|
|
@@ -309,9 +344,13 @@ module.exports = {
|
|
|
309
344
|
/** @readonly */
|
|
310
345
|
takeWhile,
|
|
311
346
|
/** @readonly */
|
|
347
|
+
take,
|
|
348
|
+
/** @readonly */
|
|
312
349
|
dropWhile,
|
|
313
350
|
/** @readonly */
|
|
314
|
-
|
|
351
|
+
drop,
|
|
352
|
+
/** @readonly */
|
|
353
|
+
scanOperator,
|
|
315
354
|
/** @readonly */
|
|
316
355
|
scanState,
|
|
317
356
|
/** @readonly */
|
|
@@ -323,6 +362,10 @@ module.exports = {
|
|
|
323
362
|
/** @readonly */
|
|
324
363
|
sum,
|
|
325
364
|
/** @readonly */
|
|
365
|
+
min,
|
|
366
|
+
/** @readonly */
|
|
367
|
+
max,
|
|
368
|
+
/** @readonly */
|
|
326
369
|
join,
|
|
327
370
|
/** @readonly */
|
|
328
371
|
entries,
|
|
@@ -331,5 +374,9 @@ module.exports = {
|
|
|
331
374
|
/** @readonly */
|
|
332
375
|
reverse,
|
|
333
376
|
/** @readonly */
|
|
334
|
-
|
|
377
|
+
zip,
|
|
378
|
+
/** @readonly */
|
|
379
|
+
equal,
|
|
380
|
+
/** @readonly */
|
|
381
|
+
countdown,
|
|
335
382
|
}
|