functionalscript 0.0.173 → 0.0.174
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 +2 -2
- package/btree/test.js +2 -1
- package/package.json +1 -1
- package/sequence/array/index.js +2 -2
- package/sequence/asyncIterable/index.js +6 -6
- package/sequence/index.js +5 -14
- package/sequence/iterable/index.js +6 -6
- package/sequence/list/index.js +83 -17
- package/sequence/list/test.js +24 -0
- package/test.js +1 -0
package/btree/index.js
CHANGED
|
@@ -336,7 +336,7 @@ const values = node => ({
|
|
|
336
336
|
const flatArray = (...array) => list.flat(list.fromArray(array))
|
|
337
337
|
|
|
338
338
|
/** @type {<T>(node: Node<T>) => list.List<T>} */
|
|
339
|
-
const valuesList = node => {
|
|
339
|
+
const valuesList = node => () => {
|
|
340
340
|
const f = () => {
|
|
341
341
|
switch (node.length) {
|
|
342
342
|
case 1: case 2: { return list.fromArray(node) }
|
|
@@ -358,7 +358,7 @@ const valuesList = node => {
|
|
|
358
358
|
}
|
|
359
359
|
}
|
|
360
360
|
}
|
|
361
|
-
return f()
|
|
361
|
+
return f()()
|
|
362
362
|
}
|
|
363
363
|
|
|
364
364
|
module.exports = {
|
package/btree/test.js
CHANGED
package/package.json
CHANGED
package/sequence/array/index.js
CHANGED
|
@@ -85,8 +85,8 @@ const splitLast = a => {
|
|
|
85
85
|
return option.map(split)(last(a))
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
/** @type {<T>(a: Array<T>) =>
|
|
89
|
-
const at =
|
|
88
|
+
/** @type {(index: number) => <T>(a: Array<T>) => readonly[T]|undefined} */
|
|
89
|
+
const at = index => a => index < a.length ? [a[index]] : undefined
|
|
90
90
|
|
|
91
91
|
module.exports = {
|
|
92
92
|
/** @readonly */
|
|
@@ -56,12 +56,12 @@ const scan = s => c => ({
|
|
|
56
56
|
})
|
|
57
57
|
|
|
58
58
|
/** @type {<T, R>(s: seq.InclusiveScan<T, R>) => (c: AsyncOrSyncIterable<T>) => AsyncIterable<R>} */
|
|
59
|
-
const inclusiveScan = s => c => concat([
|
|
59
|
+
const inclusiveScan = ([first, s]) => c => concat([first])(scan(s)(c))
|
|
60
60
|
|
|
61
61
|
/** @type {<T, R>(is: seq.InclusiveScan<T, R>) => (c: AsyncOrSyncIterable<T>) => Promise<R>} */
|
|
62
|
-
const reduce =
|
|
63
|
-
let next =
|
|
64
|
-
for await (const i of scan(
|
|
62
|
+
const reduce = ([first, s]) => async c => {
|
|
63
|
+
let next = first
|
|
64
|
+
for await (const i of scan(s)(c)) {
|
|
65
65
|
next = i
|
|
66
66
|
}
|
|
67
67
|
return next
|
|
@@ -71,7 +71,7 @@ const sum = reduce(seq.sum)
|
|
|
71
71
|
|
|
72
72
|
const join = pipe(seq.join)(reduce)
|
|
73
73
|
|
|
74
|
-
const
|
|
74
|
+
const length = reduce(seq.length)
|
|
75
75
|
|
|
76
76
|
/** @type {<T>(f: (value: T) => boolean) => (c: AsyncOrSyncIterable<T>) => AsyncIterable<T>} */
|
|
77
77
|
const takeWhile = f => c => ({
|
|
@@ -99,7 +99,7 @@ module.exports = {
|
|
|
99
99
|
/** @readonly */
|
|
100
100
|
sum,
|
|
101
101
|
/** @readonly */
|
|
102
|
-
|
|
102
|
+
length,
|
|
103
103
|
/** @readonly */
|
|
104
104
|
join,
|
|
105
105
|
/** @readonly */
|
package/sequence/index.js
CHANGED
|
@@ -22,10 +22,7 @@ const { id } = require('../function')
|
|
|
22
22
|
/**
|
|
23
23
|
* @template T
|
|
24
24
|
* @template R
|
|
25
|
-
* @typedef {
|
|
26
|
-
* readonly scan: Scan<T, R>
|
|
27
|
-
* readonly first: R
|
|
28
|
-
* }} InclusiveScan
|
|
25
|
+
* @typedef {Tuple2<R, Scan<T, R>>} InclusiveScan
|
|
29
26
|
*/
|
|
30
27
|
|
|
31
28
|
/** @type {<R, T>(operator: op.BinaryOperator<R, T>) => (prior: R) => Scan<T, R>} */
|
|
@@ -42,10 +39,7 @@ const scan = operator => {
|
|
|
42
39
|
}
|
|
43
40
|
|
|
44
41
|
/** @type {<R, T>(operator: op.BinaryOperator<R, T>) => (first: R) => InclusiveScan<T, R>} */
|
|
45
|
-
const inclusiveScan = operator => first => (
|
|
46
|
-
scan: scan(operator)(first),
|
|
47
|
-
first,
|
|
48
|
-
})
|
|
42
|
+
const inclusiveScan = operator => first => [first, scan(operator)(first)]
|
|
49
43
|
|
|
50
44
|
/**
|
|
51
45
|
* @template T
|
|
@@ -58,14 +52,11 @@ const createEntries = index => value => [[index, value], createEntries(index + 1
|
|
|
58
52
|
const entries = createEntries(0)
|
|
59
53
|
|
|
60
54
|
/** @type {(separator: string) => InclusiveScan<string, string>} */
|
|
61
|
-
const join = separator => (
|
|
62
|
-
scan: value => [value, scan(op.join(separator))(value)],
|
|
63
|
-
first: ''
|
|
64
|
-
})
|
|
55
|
+
const join = separator => ['', value => [value, scan(op.join(separator))(value)]]
|
|
65
56
|
|
|
66
57
|
const sum = inclusiveScan(op.addition)(0)
|
|
67
58
|
|
|
68
|
-
const
|
|
59
|
+
const length = inclusiveScan(a => () => a + 1)(0)
|
|
69
60
|
|
|
70
61
|
/**
|
|
71
62
|
* @template T
|
|
@@ -89,7 +80,7 @@ module.exports = {
|
|
|
89
80
|
/** @readonly */
|
|
90
81
|
sum,
|
|
91
82
|
/** @readonly */
|
|
92
|
-
|
|
83
|
+
length,
|
|
93
84
|
/** @readonly */
|
|
94
85
|
entries,
|
|
95
86
|
/** @readonly */
|
|
@@ -22,12 +22,12 @@ const scan = s => c => ({
|
|
|
22
22
|
})
|
|
23
23
|
|
|
24
24
|
/** @type {<T, R>(s: seq.InclusiveScan<T, R>) => (c: Iterable<T>) => Iterable<R>} */
|
|
25
|
-
const inclusiveScan = s => c => concat([
|
|
25
|
+
const inclusiveScan = ([first, s]) => c => concat([first])(scan(s)(c))
|
|
26
26
|
|
|
27
27
|
/** @type {<T, R>(s: seq.InclusiveScan<T, R>) => (c: Iterable<T>) => R} */
|
|
28
|
-
const reduce = s => c => {
|
|
29
|
-
let next =
|
|
30
|
-
for (const i of scan(s
|
|
28
|
+
const reduce = ([first, s]) => c => {
|
|
29
|
+
let next = first
|
|
30
|
+
for (const i of scan(s)(c)) {
|
|
31
31
|
next = i
|
|
32
32
|
}
|
|
33
33
|
return next
|
|
@@ -37,7 +37,7 @@ const entries = scan(seq.entries)
|
|
|
37
37
|
|
|
38
38
|
const sum = reduce(seq.sum)
|
|
39
39
|
|
|
40
|
-
const
|
|
40
|
+
const length = reduce(seq.length)
|
|
41
41
|
|
|
42
42
|
const join = pipe(seq.join)(reduce)
|
|
43
43
|
|
|
@@ -87,7 +87,7 @@ module.exports = {
|
|
|
87
87
|
/** @readonly */
|
|
88
88
|
sum,
|
|
89
89
|
/** @readonly */
|
|
90
|
-
|
|
90
|
+
length,
|
|
91
91
|
/** @readonly */
|
|
92
92
|
entries,
|
|
93
93
|
/** @readonly */
|
package/sequence/list/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
const array = require('../array')
|
|
2
2
|
const option = require('../../option')
|
|
3
|
+
const base = require('..')
|
|
4
|
+
const { pipe } = require('../../function')
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* @template T
|
|
@@ -21,10 +23,10 @@ const empty = () => undefined
|
|
|
21
23
|
/**
|
|
22
24
|
* @template T
|
|
23
25
|
* @template R
|
|
24
|
-
* @typedef {(list: List<T>) => List<R>}
|
|
26
|
+
* @typedef {(list: List<T>) => List<R>} ListMap
|
|
25
27
|
*/
|
|
26
28
|
|
|
27
|
-
/** @type {<T>(first: T) =>
|
|
29
|
+
/** @type {<T>(first: T) => ListMap<T, T>} */
|
|
28
30
|
const list = first => tail => () => [first, tail]
|
|
29
31
|
|
|
30
32
|
/** @type {<T>(first: T) => List<T>} */
|
|
@@ -34,43 +36,89 @@ const one = first => list(first)(empty)
|
|
|
34
36
|
const fromArray = a => {
|
|
35
37
|
/** @typedef {typeof a extends array.Array<infer T> ? T : never} T */
|
|
36
38
|
/** @type {(index: number) => List<T>} */
|
|
37
|
-
const
|
|
39
|
+
const at = index => {
|
|
38
40
|
/** @type {(value: readonly [T]) => Result<T>} */
|
|
39
|
-
const result = ([value]) => list(value)(
|
|
40
|
-
return () => option.map(result)(array.at(
|
|
41
|
+
const result = ([value]) => list(value)(at(index + 1))()
|
|
42
|
+
return () => option.map(result)(array.at(index)(a))
|
|
41
43
|
}
|
|
42
|
-
return
|
|
44
|
+
return at(0)
|
|
43
45
|
}
|
|
44
46
|
|
|
45
|
-
/** @type {<T>(list0: List<T>) =>
|
|
46
|
-
const concat =
|
|
47
|
-
/** @typedef {typeof
|
|
47
|
+
/** @type {<T>(list0: List<T>) => ListMap<T, T>} */
|
|
48
|
+
const concat = a => b => () => {
|
|
49
|
+
/** @typedef {typeof a extends List<infer T> ? T : never} T */
|
|
48
50
|
/** @type {(firstAntTail: FirstAndTail<T>) => Result<T>} */
|
|
49
|
-
const
|
|
50
|
-
return option.
|
|
51
|
+
const defined = ([first, tail]) => [first, concat(tail)(b)]
|
|
52
|
+
return option.match(defined)(b)(a())
|
|
51
53
|
}
|
|
52
54
|
|
|
53
|
-
/** @type {<T, R>(f: (value: T) => List<R>) =>
|
|
55
|
+
/** @type {<T, R>(f: (value: T) => List<R>) => ListMap<T, R>} */
|
|
54
56
|
const flatMap = f => {
|
|
55
57
|
/** @typedef {typeof f extends (value: infer T) => List<infer R> ? [T, R] : never} TR */
|
|
56
58
|
/** @typedef {TR[0]} T */
|
|
57
59
|
/** @typedef {TR[1]} R */
|
|
58
60
|
/** @type {(firstAntTail: FirstAndTail<T>) => Result<R>} */
|
|
59
|
-
const
|
|
61
|
+
const defined = ([first, tail]) => concat(f(first))(listMap(tail))()
|
|
60
62
|
/** @type {(list: List<T>) => List<R>} */
|
|
61
|
-
const
|
|
62
|
-
return
|
|
63
|
+
const listMap = list => () => option.map(defined)(list())
|
|
64
|
+
return listMap
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
/** @type {<T>(list: List<List<T>>) => List<T>} */
|
|
66
68
|
const flat = flatMap(i => i)
|
|
67
69
|
|
|
68
|
-
/** @type {<T, R>(f: (value: T) => R) =>
|
|
70
|
+
/** @type {<T, R>(f: (value: T) => R) => ListMap<T, R>} */
|
|
69
71
|
const map = f => flatMap(i => one(f(i)))
|
|
70
72
|
|
|
71
|
-
/** @type {<T>(f: (value: T) => boolean) =>
|
|
73
|
+
/** @type {<T>(f: (value: T) => boolean) => ListMap<T, T>} */
|
|
72
74
|
const filter = f => flatMap(i => f(i) ? one(i) : empty)
|
|
73
75
|
|
|
76
|
+
/** @type {<T, R>(s: base.Scan<T, R>) => ListMap<T, R>} */
|
|
77
|
+
const scan = s => input => () => {
|
|
78
|
+
/** @typedef {typeof s extends base.Scan<infer T, infer R> ? [T, R] : never} TR */
|
|
79
|
+
/** @typedef {TR[0]} T */
|
|
80
|
+
/** @typedef {TR[1]} R */
|
|
81
|
+
/** @type {(firstAndTail: FirstAndTail<T>) => Result<R>} */
|
|
82
|
+
const defined = ([first, tail]) => {
|
|
83
|
+
const [newFirst, newS] = s(first)
|
|
84
|
+
return [newFirst, scan(newS)(tail)]
|
|
85
|
+
}
|
|
86
|
+
return option.map(defined)(input())
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** @type {<T, R>(s: base.InclusiveScan<T, R>) => ListMap<T, R>} */
|
|
90
|
+
const inclusiveScan = ([first, s]) => input => list(first)(scan(s)(input))
|
|
91
|
+
|
|
92
|
+
/** @type {<T>(def: T) => (input: List<T>) => T} */
|
|
93
|
+
const last = def => input => {
|
|
94
|
+
let i = input()
|
|
95
|
+
let r = def
|
|
96
|
+
while (i !== undefined) {
|
|
97
|
+
r = i[0]
|
|
98
|
+
i = i[1]()
|
|
99
|
+
}
|
|
100
|
+
return r
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** @type {<T, R>(s: base.InclusiveScan<T, R>) => (input: List<T>) => R} */
|
|
104
|
+
const reduce = s => input => last(s[0])(inclusiveScan(s)(input))
|
|
105
|
+
|
|
106
|
+
const entries = scan(base.entries)
|
|
107
|
+
|
|
108
|
+
const sum = reduce(base.sum)
|
|
109
|
+
|
|
110
|
+
const length = reduce(base.length)
|
|
111
|
+
|
|
112
|
+
const join = pipe(base.join)(reduce)
|
|
113
|
+
|
|
114
|
+
/** @type {<T>(f: (value: T) => boolean) => (input: List<T>) => T|undefined} */
|
|
115
|
+
const find = f => input => {
|
|
116
|
+
/** @typedef {typeof f extends (value: infer T) => boolean ? T : never} T */
|
|
117
|
+
/** @type {(result: FirstAndTail<T>) => T} */
|
|
118
|
+
const defined = ([first]) => first
|
|
119
|
+
return option.map(defined)(filter(f)(input)())
|
|
120
|
+
}
|
|
121
|
+
|
|
74
122
|
/**
|
|
75
123
|
* Note: probably, it's possible to implement using the `scan` concept.
|
|
76
124
|
* @type {<T>(list: List<T>) => Iterable<T>}
|
|
@@ -106,4 +154,22 @@ module.exports = {
|
|
|
106
154
|
map,
|
|
107
155
|
/** @readonly */
|
|
108
156
|
filter,
|
|
157
|
+
/** @readonly */
|
|
158
|
+
scan,
|
|
159
|
+
/** @readonly */
|
|
160
|
+
inclusiveScan,
|
|
161
|
+
/** @readonly */
|
|
162
|
+
last,
|
|
163
|
+
/** @readonly */
|
|
164
|
+
reduce,
|
|
165
|
+
/** @readonly */
|
|
166
|
+
entries,
|
|
167
|
+
/** @readonly */
|
|
168
|
+
sum,
|
|
169
|
+
/** @readonly */
|
|
170
|
+
join,
|
|
171
|
+
/** @readonly */
|
|
172
|
+
length,
|
|
173
|
+
/** @readonly */
|
|
174
|
+
find,
|
|
109
175
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const list = require('.')
|
|
2
|
+
const { sum } = require('..')
|
|
3
|
+
|
|
4
|
+
/** @type {<T>(l: list.List<T>) => void} */
|
|
5
|
+
const print = a => {
|
|
6
|
+
let i = a()
|
|
7
|
+
while (i !== undefined) {
|
|
8
|
+
console.log(i[0])
|
|
9
|
+
i = i[1]()
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
{
|
|
14
|
+
const big = list.fromArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 42, 60])
|
|
15
|
+
print(big)
|
|
16
|
+
/*
|
|
17
|
+
const list0 = list.fromArray([0, 1, 2, 3])
|
|
18
|
+
const list1 = list.flatMap(x => list.fromArray([x, x * 2, x * 3]))(list0)
|
|
19
|
+
const list2 = list.concat(list0)(list0)
|
|
20
|
+
const list3 = list.inclusiveScan(sum)(list0)
|
|
21
|
+
print(list3)
|
|
22
|
+
const r = list.find(x => x === 42)(list.fromArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 42, 60]))
|
|
23
|
+
*/
|
|
24
|
+
}
|