functionalscript 0.0.210 → 0.0.215
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/FUNDING.yml +12 -0
- package/function/index.js +2 -2
- package/json/index.js +2 -2
- package/json/test.js +4 -4
- package/map/index.js +0 -1
- package/module-manager/index.js +2 -2
- package/package.json +1 -1
- package/sequence/asyncIterable/index.js +2 -2
- package/sequence/index.js +28 -9
- package/sequence/iterable/index.js +2 -3
- package/sequence/iterable/test.js +2 -2
- package/sequence/test.js +34 -25
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# These are supported funding model platforms
|
|
2
|
+
|
|
3
|
+
github: [sergey-shandar] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
|
4
|
+
patreon: # Replace with a single Patreon username
|
|
5
|
+
open_collective: # Replace with a single Open Collective username
|
|
6
|
+
ko_fi: # Replace with a single Ko-fi username
|
|
7
|
+
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
|
8
|
+
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
|
9
|
+
liberapay: # Replace with a single Liberapay username
|
|
10
|
+
issuehunt: # Replace with a single IssueHunt username
|
|
11
|
+
otechie: # Replace with a single Otechie username
|
|
12
|
+
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
package/function/index.js
CHANGED
package/json/index.js
CHANGED
|
@@ -2,7 +2,7 @@ const seq = require('../sequence')
|
|
|
2
2
|
const op = require('../sequence/operator')
|
|
3
3
|
const object = require('../object')
|
|
4
4
|
const array = require('../sequence/array')
|
|
5
|
-
const { compose
|
|
5
|
+
const { compose } = require('../function')
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* @typedef {{
|
|
@@ -24,7 +24,7 @@ const addProperty = value => {
|
|
|
24
24
|
const [name, tail] = result
|
|
25
25
|
return { ...srcObject, [name]: f(tail)(object.at(name)(srcObject)) }
|
|
26
26
|
}
|
|
27
|
-
return
|
|
27
|
+
return compose(f)(array.sequence)
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
/** @type {(_: string) => seq.Sequence<string>} */
|
package/json/test.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const json = require('.')
|
|
2
2
|
const { sort } = require('../object')
|
|
3
|
-
const {
|
|
3
|
+
const { identity } = require('../function')
|
|
4
4
|
|
|
5
5
|
if (json.addProperty("Hello")([])({}) !== "Hello") { throw 'error' }
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@ if (json.addProperty("Hello")([])({}) !== "Hello") { throw 'error' }
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
{
|
|
13
|
-
const x = json.stringify(
|
|
13
|
+
const x = json.stringify(identity)(json.addProperty("Hello")(['a'])({}))
|
|
14
14
|
if (x !== '{"a":"Hello"}') { throw x }
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -20,7 +20,7 @@ if (json.addProperty("Hello")([])({}) !== "Hello") { throw 'error' }
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
{
|
|
23
|
-
const x = json.stringify(
|
|
23
|
+
const x = json.stringify(identity)(json.addProperty("Hello")(['a'])({ c: [], b: 12 }))
|
|
24
24
|
if (x !== '{"c":[],"b":12,"a":"Hello"}') { throw x }
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -34,6 +34,6 @@ if (json.addProperty("Hello")([])({}) !== "Hello") { throw 'error' }
|
|
|
34
34
|
{
|
|
35
35
|
const _0 = { a: { y: [24] }, c: [], b: 12 }
|
|
36
36
|
const _1 = json.addProperty("Hello")(['a', 'x'])(_0)
|
|
37
|
-
const _2 = json.stringify(
|
|
37
|
+
const _2 = json.stringify(identity)(_1)
|
|
38
38
|
if (_2 !== '{"a":{"y":[24],"x":"Hello"},"c":[],"b":12}') { throw _2 }
|
|
39
39
|
}
|
package/map/index.js
CHANGED
package/module-manager/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const array = require('../sequence/array')
|
|
2
|
-
const { compose
|
|
2
|
+
const { compose } = require('../function')
|
|
3
3
|
const option = require('../option')
|
|
4
4
|
const { head, last, splitLast, splitFirst } = array
|
|
5
5
|
const iter = require('../sequence/iterable')
|
|
@@ -88,7 +88,7 @@ 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
|
|
91
|
+
return compose
|
|
92
92
|
(option.map(defined))
|
|
93
93
|
(sf)
|
|
94
94
|
}
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { compose
|
|
1
|
+
const { compose } = 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 = compose(reduce)(seq.join)
|
|
73
73
|
|
|
74
74
|
const length = reduce(seq.length)
|
|
75
75
|
|
package/sequence/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const seqOp = require('./operator')
|
|
2
|
-
const { compose
|
|
2
|
+
const { compose } = require('../function')
|
|
3
3
|
const op = require('../function/operator')
|
|
4
4
|
const { logicalNot, strictEqual } = require('../function/operator')
|
|
5
5
|
|
|
@@ -18,7 +18,7 @@ const { logicalNot, strictEqual } = require('../function/operator')
|
|
|
18
18
|
*
|
|
19
19
|
* Please note that the sequence also contains `Concat<T>. We need this as
|
|
20
20
|
* a workaround because modern JavaScript implementations don't support
|
|
21
|
-
* ES6 TCO (Tail Call Optimization). Without this
|
|
21
|
+
* ES6 TCO (Tail Call Optimization). Without this workaround, we may have
|
|
22
22
|
* a stack overflow if a list contains a lot of concateneted lists.
|
|
23
23
|
*
|
|
24
24
|
* @template T
|
|
@@ -37,6 +37,9 @@ const { logicalNot, strictEqual } = require('../function/operator')
|
|
|
37
37
|
|
|
38
38
|
const empty = () => undefined
|
|
39
39
|
|
|
40
|
+
/** @type {<T>(first: T) => (tail: Sequence<T>) => Sequence<T>} */
|
|
41
|
+
const sequence = first => tail => () => [first, tail]
|
|
42
|
+
|
|
40
43
|
/** @type {<F, T>(a: readonly[F, Sequence<T>]) => (b: Sequence<T>) => readonly[F, Sequence<T>]} */
|
|
41
44
|
const norm = ([a0, a1]) => b => [a0, [a1, b]]
|
|
42
45
|
|
|
@@ -78,7 +81,7 @@ const first = input => {
|
|
|
78
81
|
*/
|
|
79
82
|
|
|
80
83
|
/**
|
|
81
|
-
* Note: the operation is not lazy. It
|
|
84
|
+
* Note: the operation is not lazy. It traverses the given array and creates a linked list.
|
|
82
85
|
*
|
|
83
86
|
* @type {<T>(...array: readonly T[]) => Sequence<T>}
|
|
84
87
|
*/
|
|
@@ -86,14 +89,12 @@ const list = (...array) => {
|
|
|
86
89
|
/** @typedef {typeof array extends readonly(infer T)[] ? T : never} T */
|
|
87
90
|
let i = array.length
|
|
88
91
|
/** @type {Sequence<T>} */
|
|
89
|
-
let
|
|
92
|
+
let iResult = empty
|
|
90
93
|
while (i !== 0) {
|
|
91
94
|
i = i - 1
|
|
92
|
-
|
|
93
|
-
const listResult = [array[i], result]
|
|
94
|
-
result = () => listResult
|
|
95
|
+
iResult = sequence(array[i])(iResult)
|
|
95
96
|
}
|
|
96
|
-
return
|
|
97
|
+
return iResult
|
|
97
98
|
}
|
|
98
99
|
|
|
99
100
|
/** @type {<T>(...array: readonly Sequence<T>[]) => Sequence<T>} */
|
|
@@ -228,7 +229,7 @@ const some = f => input => find(x => x)(map(f)(input)) !== undefined
|
|
|
228
229
|
const includes = value => some(strictEqual(value))
|
|
229
230
|
|
|
230
231
|
/** @type {<T>(f: (value: T) => boolean) => SequenceReduce<T, boolean>} */
|
|
231
|
-
const every = f => input => !some(
|
|
232
|
+
const every = f => input => !some(compose(logicalNot)(f))(input)
|
|
232
233
|
|
|
233
234
|
/** @type {<T>(list: Sequence<T>) => Iterable<T>} */
|
|
234
235
|
const iterable = list => ({
|
|
@@ -265,6 +266,20 @@ const zip = a => b => () => {
|
|
|
265
266
|
return [[resultA[0], resultB[0]], zip(resultA[1])(resultB[1])]
|
|
266
267
|
}
|
|
267
268
|
|
|
269
|
+
/** @type {<T>(s: Sequence<T>) => Sequence<T>} */
|
|
270
|
+
const reverse = s => {
|
|
271
|
+
/** @type {typeof s} */
|
|
272
|
+
let iResult = empty
|
|
273
|
+
let iSource = s
|
|
274
|
+
while (true) {
|
|
275
|
+
const result = next(iSource)
|
|
276
|
+
if (result === undefined) { return iResult }
|
|
277
|
+
const [first, tail] = result
|
|
278
|
+
iResult = sequence(first)(iResult)
|
|
279
|
+
iSource = tail
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
268
283
|
module.exports = {
|
|
269
284
|
/** @readonly */
|
|
270
285
|
next,
|
|
@@ -273,6 +288,8 @@ module.exports = {
|
|
|
273
288
|
/** @readonly */
|
|
274
289
|
empty,
|
|
275
290
|
/** @readonly */
|
|
291
|
+
sequence,
|
|
292
|
+
/** @readonly */
|
|
276
293
|
at,
|
|
277
294
|
/** @readonly */
|
|
278
295
|
concat,
|
|
@@ -326,4 +343,6 @@ module.exports = {
|
|
|
326
343
|
includes,
|
|
327
344
|
/** @readonly */
|
|
328
345
|
zip,
|
|
346
|
+
/** @readonly */
|
|
347
|
+
reverse,
|
|
329
348
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
const {
|
|
2
|
-
const { compose: combine } = require('../../function')
|
|
1
|
+
const { compose } = require('../../function')
|
|
3
2
|
const seq = require('../operator')
|
|
4
3
|
|
|
5
4
|
/** @type {<T>(a: Iterable<T>) => (b: Iterable<T>) => Iterable<T>} */
|
|
@@ -40,7 +39,7 @@ const sum = reduce(seq.sum)
|
|
|
40
39
|
|
|
41
40
|
const length = reduce(seq.length)
|
|
42
41
|
|
|
43
|
-
const join =
|
|
42
|
+
const join = compose(reduce)(seq.join)
|
|
44
43
|
|
|
45
44
|
/** @type {<T, R>(f: (value: T) => Iterable<R>) => (c: Iterable<T>) => Iterable<R>} */
|
|
46
45
|
const flatMap = f => c => ({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const i = require('.')
|
|
2
|
-
const { compose
|
|
2
|
+
const { compose } = require('../../function')
|
|
3
3
|
|
|
4
4
|
{
|
|
5
5
|
const r = i.sum([120, 300, 42])
|
|
@@ -33,7 +33,7 @@ const { compose: combine } = require('../../function')
|
|
|
33
33
|
/** @type {(_: string) => string|undefined} */
|
|
34
34
|
const file = _ => 'x'
|
|
35
35
|
/** @type {(_: string) => string|undefined} */
|
|
36
|
-
const x = p =>
|
|
36
|
+
const x = p => compose
|
|
37
37
|
(i.find(x => x !== undefined))
|
|
38
38
|
(i.map(x => file(x())))
|
|
39
39
|
([() => p, () => `${p}.js`, () => `${p}/index.js`])
|
package/sequence/test.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
const seq = require('.')
|
|
2
|
+
const { empty, next, list, flatMap, concat, exclusiveScan, find, every, some, first, drop, map, generate } = require('.')
|
|
2
3
|
const { sum } = require('./operator')
|
|
3
|
-
const op = require('./operator')
|
|
4
4
|
const array = require('./array')
|
|
5
|
+
const json = require('../json')
|
|
6
|
+
const { identity } = require('../function')
|
|
5
7
|
|
|
6
8
|
/** @type {<T>(input: seq.Sequence<T>) => void} */
|
|
7
9
|
const print = input => {
|
|
8
10
|
let i = input
|
|
9
11
|
while (true) {
|
|
10
|
-
const result =
|
|
12
|
+
const result = next(i)
|
|
11
13
|
if (result === undefined) { return }
|
|
12
14
|
console.log(result[0])
|
|
13
15
|
i = result[1]
|
|
@@ -15,47 +17,47 @@ const print = input => {
|
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
{
|
|
18
|
-
const big =
|
|
19
|
-
const list0 =
|
|
20
|
-
const list1 =
|
|
21
|
-
const list2 =
|
|
22
|
-
const list3 =
|
|
23
|
-
const r =
|
|
24
|
-
if (
|
|
25
|
-
if (
|
|
26
|
-
if (
|
|
27
|
-
if (
|
|
28
|
-
if (
|
|
20
|
+
const big = list(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 42, 60)
|
|
21
|
+
const list0 = list(0, 1, 2, 3)
|
|
22
|
+
const list1 = flatMap(x => list(x, x * 2, x * 3))(list0)
|
|
23
|
+
const list2 = concat(list0, list0)
|
|
24
|
+
const list3 = exclusiveScan(sum)(list0)
|
|
25
|
+
const r = find(x => x === 42)(big)
|
|
26
|
+
if (every(x => x > 0)(big) !== true) { throw 'x' }
|
|
27
|
+
if (every(x => x < 20)(big) !== false) { throw 'x' }
|
|
28
|
+
if (some(x => x > 100)(big) !== false) { throw 'x' }
|
|
29
|
+
if (some(x => x > 50)(big) !== true) { throw 'x' }
|
|
30
|
+
if (first(drop(16)(big)) !== 42) { throw 'drop' }
|
|
29
31
|
{
|
|
30
|
-
const a =
|
|
32
|
+
const a = map(generate)(generate(100_000))
|
|
31
33
|
const ar = array.fromSequence(a)
|
|
32
|
-
// This operation
|
|
34
|
+
// This operation uses a lot of stack because `...`
|
|
33
35
|
// puts array items on a stack.
|
|
34
36
|
// Use `array.sequence` instead
|
|
35
|
-
const x =
|
|
36
|
-
const r =
|
|
37
|
+
const x = concat(...ar)
|
|
38
|
+
const r = next(x)
|
|
37
39
|
// print(x)
|
|
38
40
|
}
|
|
39
41
|
{
|
|
40
|
-
const a = array.fromSequence(
|
|
41
|
-
let x =
|
|
42
|
-
const r =
|
|
42
|
+
const a = array.fromSequence(generate(1_000_000))
|
|
43
|
+
let x = concat(array.sequence(a), big)
|
|
44
|
+
const r = next(x)
|
|
43
45
|
// print(x)
|
|
44
46
|
}
|
|
45
47
|
{
|
|
46
48
|
let x = big
|
|
47
49
|
for (let i = 0; i < 1_000_000; ++i) {
|
|
48
|
-
x =
|
|
50
|
+
x = concat(empty, x)
|
|
49
51
|
}
|
|
50
|
-
const r =
|
|
52
|
+
const r = next(x)
|
|
51
53
|
// print(x)
|
|
52
|
-
}
|
|
54
|
+
}
|
|
53
55
|
{
|
|
54
56
|
let x = big
|
|
55
57
|
for (let i = 0; i < 1_000_000; ++i) {
|
|
56
|
-
x =
|
|
58
|
+
x = concat(x, list(i))
|
|
57
59
|
}
|
|
58
|
-
const r =
|
|
60
|
+
const r = next(x)
|
|
59
61
|
// print(x)
|
|
60
62
|
}
|
|
61
63
|
}
|
|
@@ -64,3 +66,10 @@ const print = input => {
|
|
|
64
66
|
const x = seq.join(':')(seq.list("1", "2", "3", "4", "5", "6"))
|
|
65
67
|
if (x !== "1:2:3:4:5:6") { throw x }
|
|
66
68
|
}
|
|
69
|
+
|
|
70
|
+
{
|
|
71
|
+
const r = seq.reverse(seq.list(1, 2, 3, 4))
|
|
72
|
+
const s = array.fromSequence(r)
|
|
73
|
+
const j = json.stringify(identity)(s)
|
|
74
|
+
if (j !== '[4,3,2,1]') { throw j }
|
|
75
|
+
}
|