functionalscript 0.0.238 → 0.0.242
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/node.js.yml +0 -2
- package/commonjs/README.md +55 -0
- package/commonjs/module/index.js +23 -10
- package/commonjs/package/dependencies/index.js +1 -1
- package/commonjs/package/dependencies/test.js +0 -3
- package/commonjs/package/index.js +7 -2
- package/commonjs/path/index.js +9 -9
- package/commonjs/run/index.js +1 -1
- package/io/commonjs/index.js +1 -1
- package/io/commonjs/test.js +1 -1
- package/io/nodejs/version/index.js +1 -6
- package/json/index.js +16 -16
- package/package.json +9 -2
- package/test.js +1 -1
- package/tsconfig.json +1 -1
- package/types/array/index.js +1 -1
- package/types/btree/index.js +23 -25
- package/types/btree/test.js +2 -2
- package/types/function/operator/index.js +51 -11
- package/types/list/index.js +372 -0
- package/types/{sequence → list}/test.js +32 -19
- package/types/map/index.js +40 -46
- package/types/map/test.js +35 -34
- package/types/object/index.js +3 -3
- package/types/sequence/README.md +0 -68
- package/types/sequence/index.js +0 -382
package/types/map/test.js
CHANGED
|
@@ -1,59 +1,60 @@
|
|
|
1
|
-
const { empty } = require('.')
|
|
2
|
-
const
|
|
1
|
+
const { at, set, empty, entries } = require('.')
|
|
2
|
+
const seq = require('../list')
|
|
3
3
|
|
|
4
4
|
{
|
|
5
|
-
let m =
|
|
5
|
+
let m = set('a')(1)(undefined)
|
|
6
6
|
|
|
7
|
-
if (
|
|
8
|
-
if (
|
|
7
|
+
if (at('a')(m) !== 1) { throw 'error' }
|
|
8
|
+
if (at('b')(m) !== undefined) { throw 'error' }
|
|
9
9
|
|
|
10
|
-
m =
|
|
10
|
+
m = set('b')(2)(m)
|
|
11
11
|
|
|
12
|
-
if (
|
|
13
|
-
if (
|
|
14
|
-
if (
|
|
12
|
+
if (at('a')(m) !== 1) { throw 'error' }
|
|
13
|
+
if (at('b')(m) !== 2) { throw 'error' }
|
|
14
|
+
if (at('c')(m) !== undefined) { throw 'error' }
|
|
15
15
|
|
|
16
|
-
m =
|
|
16
|
+
m = set('z')(3)(m)
|
|
17
17
|
|
|
18
|
-
if (
|
|
19
|
-
if (
|
|
20
|
-
if (
|
|
21
|
-
if (
|
|
18
|
+
if (at('a')(m) !== 1) { throw 'error' }
|
|
19
|
+
if (at('b')(m) !== 2) { throw 'error' }
|
|
20
|
+
if (at('z')(m) !== 3) { throw 'error' }
|
|
21
|
+
if (at('')(m) !== undefined) { throw 'error' }
|
|
22
22
|
|
|
23
|
-
m =
|
|
23
|
+
m = set('')(4)(m)
|
|
24
24
|
|
|
25
|
-
if (
|
|
26
|
-
if (
|
|
27
|
-
if (
|
|
28
|
-
if (
|
|
29
|
-
if (
|
|
25
|
+
if (at('a')(m) !== 1) { throw 'error' }
|
|
26
|
+
if (at('b')(m) !== 2) { throw 'error' }
|
|
27
|
+
if (at('z')(m) !== 3) { throw 'error' }
|
|
28
|
+
if (at('')(m) !== 4) { throw 'error' }
|
|
29
|
+
if (at('Hello world!')(m) !== undefined) { throw 'error' }
|
|
30
30
|
|
|
31
|
-
m =
|
|
31
|
+
m = set('Hello world!')(42)(m)
|
|
32
32
|
|
|
33
|
-
if (
|
|
34
|
-
if (
|
|
35
|
-
if (
|
|
36
|
-
if (
|
|
37
|
-
if (
|
|
38
|
-
if (
|
|
33
|
+
if (at('a')(m) !== 1) { throw 'error' }
|
|
34
|
+
if (at('b')(m) !== 2) { throw 'error' }
|
|
35
|
+
if (at('z')(m) !== 3) { throw 'error' }
|
|
36
|
+
if (at('')(m) !== 4) { throw 'error' }
|
|
37
|
+
if (at('Hello world!')(m) !== 42) { throw 'error' }
|
|
38
|
+
if (at('x')(m) !== undefined) { throw 'error' }
|
|
39
39
|
|
|
40
40
|
// console.log(Array.from(m.entries()))
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
{
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (
|
|
47
|
-
if (
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
let m = set('x')(12)(undefined)
|
|
45
|
+
m = set('y')(44)(m)
|
|
46
|
+
if (at('x')(m) !== 12) { throw 'error' }
|
|
47
|
+
if (at('y')(m) !== 44) { throw 'error' }
|
|
48
|
+
if (at('a')(m) !== undefined) { throw 'error' }
|
|
49
|
+
const e = seq.toArray(entries(m))
|
|
50
|
+
if (e.length !== 2) { throw 'error' }
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
{
|
|
53
54
|
/** @type {import('.').Map<number>} */
|
|
54
55
|
let m = empty
|
|
55
56
|
for (let i = 0; i < 100_000; ++i) {
|
|
56
|
-
m =
|
|
57
|
+
m = set((i * i).toString())(i)(m)
|
|
57
58
|
/*
|
|
58
59
|
console.log()
|
|
59
60
|
console.log(`# ${i}`)
|
package/types/object/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const seq = require('../
|
|
1
|
+
const seq = require('../list')
|
|
2
2
|
const map = require('../map')
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -16,8 +16,8 @@ const map = require('../map')
|
|
|
16
16
|
/** @type {(name: string) => <T>(object: Map<T>) => T|undefined} */
|
|
17
17
|
const at = name => object => Object.getOwnPropertyDescriptor(object, name)?.value
|
|
18
18
|
|
|
19
|
-
/** @type {<T>(entries: seq.
|
|
20
|
-
const sort = entries => map.fromEntries(entries)
|
|
19
|
+
/** @type {<T>(entries: seq.List<Entry<T>>) => seq.List<Entry<T>>} */
|
|
20
|
+
const sort = entries => map.entries(map.fromEntries(entries))
|
|
21
21
|
|
|
22
22
|
module.exports = {
|
|
23
23
|
/** @readonly */
|
package/types/sequence/README.md
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
# Sequences
|
|
2
|
-
|
|
3
|
-
Sequence types:
|
|
4
|
-
|
|
5
|
-
- Sequence
|
|
6
|
-
- Array
|
|
7
|
-
- Iterable
|
|
8
|
-
- AsyncIterable
|
|
9
|
-
|
|
10
|
-
# Sequence Types
|
|
11
|
-
|
|
12
|
-
```ts
|
|
13
|
-
type Sequence<T> =
|
|
14
|
-
readonly T[] |
|
|
15
|
-
Thunk<T> |
|
|
16
|
-
|
|
17
|
-
type Thunk<T> = () => Node<T>
|
|
18
|
-
|
|
19
|
-
type Node<T> =
|
|
20
|
-
undefined |
|
|
21
|
-
{ readonly first: T, readonly tail: Sequence<T> } |
|
|
22
|
-
readonly[Sequence<T>, Sequence<T>]
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## Functions
|
|
26
|
-
|
|
27
|
-
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
|
|
28
|
-
|
|
29
|
-
- `length: Sequence<infer T> => number`
|
|
30
|
-
- `at: number => Sequence<infer T> = T|undefined`
|
|
31
|
-
- `concat: Sequence<infer T> => Sequence<T> => Sequence<T>`
|
|
32
|
-
- `entries: Sequence<infer T> => Sequence<[number, T]>`
|
|
33
|
-
- `every: (infer T => boolean) => Sequence<T> => boolean`
|
|
34
|
-
- `filter: (infer T => boolean) => Sequence<T> => Sequence<T>`
|
|
35
|
-
- `find: (infer T => boolean) => Sequence<T> => T`
|
|
36
|
-
- `findIndex: (infer T => boolean) => Sequence<T> => number`
|
|
37
|
-
- `flat: Sequence<Sequence<T>> => Sequence<T>`
|
|
38
|
-
- `flatMap: (infer T => Sequence<infer R>) => Sequence<T> => Sequence<R>`
|
|
39
|
-
- `includes: infer T => Sequence<T> => boolean`
|
|
40
|
-
- `indexOf: infer T => Sequence<T> => number`
|
|
41
|
-
- `join: string => Sequence<string> => string`
|
|
42
|
-
- `lastIndexOf: infer T => Sequence<T> => number`
|
|
43
|
-
- `map: (infer T => infer R) => Sequence<T> => Sequence<R>`
|
|
44
|
-
- `reduce: ...Scan<T, R> => Sequence<T> => R`
|
|
45
|
-
- `some: (infer T => boolean) => Sequence<T> => boolean`
|
|
46
|
-
|
|
47
|
-
### Priority 2.
|
|
48
|
-
|
|
49
|
-
- `slice: number => number => Sequence<T> => Sequence<T>`
|
|
50
|
-
- `reduceRight: ...Scan<T, R> => Sequence<T> => R`
|
|
51
|
-
- `toLocalString: Locales => Sequence<T> => string`
|
|
52
|
-
|
|
53
|
-
### Priority 3.
|
|
54
|
-
|
|
55
|
-
- `keys: Sequence<T> => Sequence<string>`
|
|
56
|
-
- `values: Sequence<infer T> => Sequence<T>`
|
|
57
|
-
|
|
58
|
-
## Prohibited Array Operations
|
|
59
|
-
|
|
60
|
-
- `copyWithin`
|
|
61
|
-
- `fill`
|
|
62
|
-
- `pop`
|
|
63
|
-
- `push`
|
|
64
|
-
- `reverse`
|
|
65
|
-
- `shift`
|
|
66
|
-
- `sort`
|
|
67
|
-
- `splice`
|
|
68
|
-
- `unshift`
|
package/types/sequence/index.js
DELETED
|
@@ -1,382 +0,0 @@
|
|
|
1
|
-
const { compose, identity } = require('../function')
|
|
2
|
-
const { logicalNot, strictEqual, addition } = require('../function/operator')
|
|
3
|
-
const op = require('../function/operator')
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @template T
|
|
7
|
-
* @typedef { readonly T[] | Thunk<T> } Sequence<T>
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* @template T
|
|
12
|
-
* @typedef { () => Node<T> } Thunk
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* @template T
|
|
17
|
-
* @typedef { Result<T> | Concat<T> } Node<T>
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* @template T
|
|
22
|
-
* @typedef { readonly[Sequence<T>, Sequence<T>] } Concat<T>
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* @template T
|
|
27
|
-
* @typedef { undefined | ResultOne<T> } Result
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @template T
|
|
32
|
-
* @typedef {{ readonly first: T, readonly tail: Sequence<T> }} ResultOne
|
|
33
|
-
*/
|
|
34
|
-
|
|
35
|
-
const empty = () => undefined
|
|
36
|
-
|
|
37
|
-
/** @type {<T>(first: T) => (tail: Sequence<T>) => Sequence<T>} */
|
|
38
|
-
const sequence = first => tail => () => ({ first, tail })
|
|
39
|
-
|
|
40
|
-
/** @type {<T>(sequence: Sequence<T>) => Node<T>} */
|
|
41
|
-
const nodeOne = sequence => [empty, sequence]
|
|
42
|
-
|
|
43
|
-
/** @type {<T>(array: readonly T[]) => Result<T>} */
|
|
44
|
-
const fromArray = array => {
|
|
45
|
-
/** @typedef {typeof array extends readonly(infer T)[] ? T : never} T */
|
|
46
|
-
/** @type {(index: number) => Result<T>} */
|
|
47
|
-
const at = index => {
|
|
48
|
-
if (array.length <= index) { return undefined }
|
|
49
|
-
return { first: array[index], tail: () => at(index + 1) }
|
|
50
|
-
}
|
|
51
|
-
return at(0)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/** @type {<T>(sequence: Sequence<T>) => Node<T>} */
|
|
55
|
-
const node = sequence => sequence instanceof Array ? fromArray(sequence) : sequence()
|
|
56
|
-
|
|
57
|
-
/** @type {<T>(a: Sequence<T>) => (b: Sequence<T>) => Thunk<T>} */
|
|
58
|
-
const concat = a => b => () => [a, b]
|
|
59
|
-
|
|
60
|
-
/** @type {<T>(sequence: Sequence<T>) => Result<T>} */
|
|
61
|
-
const next = sequence => {
|
|
62
|
-
let i = sequence
|
|
63
|
-
while (true) {
|
|
64
|
-
const n = node(i)
|
|
65
|
-
if (!(n instanceof Array)) { return n }
|
|
66
|
-
const [a, b] = n
|
|
67
|
-
const aNode = node(a)
|
|
68
|
-
if (aNode === undefined) {
|
|
69
|
-
i = b
|
|
70
|
-
} else if (aNode instanceof Array) {
|
|
71
|
-
const [aa, ab] = aNode
|
|
72
|
-
i = concat(aa)(concat(ab)(b))
|
|
73
|
-
} else {
|
|
74
|
-
const { first, tail } = aNode
|
|
75
|
-
return { first, tail: concat(tail)(b) }
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/** @type {<T>(sequence: Sequence<T>) => Iterable<T>} */
|
|
81
|
-
const iterable = sequence => ({
|
|
82
|
-
*[Symbol.iterator]() {
|
|
83
|
-
let i = sequence
|
|
84
|
-
while (true) {
|
|
85
|
-
const n = next(i)
|
|
86
|
-
if (n === undefined) { return }
|
|
87
|
-
const { first, tail } = n
|
|
88
|
-
yield first
|
|
89
|
-
i = tail
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
/** @type {<T>(sequence: Sequence<T>) => readonly T[]} */
|
|
95
|
-
const toArray = sequence => {
|
|
96
|
-
if (sequence instanceof Array) { return sequence }
|
|
97
|
-
return Array.from(iterable(sequence))
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/** @type {<I, O>(step: (result: ResultOne<I>) => Node<O>) => (input: Sequence<I>) => Thunk<O>} */
|
|
101
|
-
const apply = f => input => () => {
|
|
102
|
-
const n = next(input)
|
|
103
|
-
if (n === undefined) { return undefined }
|
|
104
|
-
return f(n)
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/** @type {<T>(result: ResultOne<Sequence<T>>) => Node<T>} */
|
|
108
|
-
const flatStep = ({first, tail}) => [first, flat(tail)]
|
|
109
|
-
|
|
110
|
-
/** @type {<T>(sequence: Sequence<Sequence<T>>) => Thunk<T>} */
|
|
111
|
-
const flat = apply(flatStep)
|
|
112
|
-
|
|
113
|
-
/** @type {<I, O>(f: (value: I) => O) => (result: ResultOne<I>) => Node<O>} */
|
|
114
|
-
const mapStep = f => ({ first, tail }) => ({ first: f(first), tail: map(f)(tail) })
|
|
115
|
-
|
|
116
|
-
/** @type {<I, O>(f: (value: I) => O) => (input: Sequence<I>) => Thunk<O>} */
|
|
117
|
-
const map = f => apply(mapStep(f))
|
|
118
|
-
|
|
119
|
-
/** @type {<I, O>(f: (value: I) => Sequence<O>) => (input: Sequence<I>) => Thunk<O>} */
|
|
120
|
-
const flatMap = f => compose(map(f))(flat)
|
|
121
|
-
|
|
122
|
-
/** @type {<T>(f: (value: T) => boolean) => (result: ResultOne<T>) => Node<T>} */
|
|
123
|
-
const filterStep = f => ({ first, tail }) => {
|
|
124
|
-
const fTail = filter(f)(tail)
|
|
125
|
-
return f(first) ? { first, tail: fTail } : nodeOne(fTail)
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/** @type {<T>(f: (value: T) => boolean) => (input: Sequence<T>) => Thunk<T>} */
|
|
129
|
-
const filter = f => apply(filterStep(f))
|
|
130
|
-
|
|
131
|
-
/** @type {<I, O>(f: (value: I) => O|undefined) => (result: ResultOne<I>) => Node<O>} */
|
|
132
|
-
const filterMapStep = f => ({first, tail}) => {
|
|
133
|
-
const fFirst = f(first)
|
|
134
|
-
const fTail = filterMap(f)(tail)
|
|
135
|
-
return fFirst === undefined ? nodeOne(fTail) : { first: fFirst, tail: fTail }
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/** @type {<I, O>(f: (value: I) => O|undefined) => (input: Sequence<I>) => Thunk<O>} */
|
|
139
|
-
const filterMap = f => apply(filterMapStep(f))
|
|
140
|
-
|
|
141
|
-
/** @type {<T>(f: (value: T) => boolean) => (result: ResultOne<T>) => Node<T>} */
|
|
142
|
-
const takeWhileStep = f => ({ first, tail }) => f(first) ? { first, tail: takeWhile(f)(tail) } :undefined
|
|
143
|
-
|
|
144
|
-
/** @type {<T>(f: (value: T) => boolean) => (input: Sequence<T>) => Thunk<T>} */
|
|
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))
|
|
152
|
-
|
|
153
|
-
/** @type {<T>(f: (value: T) => boolean) => (result: ResultOne<T>) => Node<T>} */
|
|
154
|
-
const dropWhileStep = f => result => {
|
|
155
|
-
const { first, tail } = result
|
|
156
|
-
return f(first) ? nodeOne(dropWhile(f)(tail)) : result
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/** @type {<T>(f: (value: T) => boolean) => (input: Sequence<T>) => Thunk<T>} */
|
|
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))
|
|
167
|
-
|
|
168
|
-
/** @type {<D>(def: D) => <T>(input: Sequence<T>) => D|T} */
|
|
169
|
-
const first = def => input => {
|
|
170
|
-
const result = next(input)
|
|
171
|
-
if (result === undefined) { return def }
|
|
172
|
-
return result.first
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/** @type {<D>(def: D) => <T>(input: Sequence<T>) => D|T} */
|
|
176
|
-
const last = def => input => {
|
|
177
|
-
/** @typedef {typeof input extends Sequence<infer T> ? T : never} T */
|
|
178
|
-
/** @type {(typeof def)|T} */
|
|
179
|
-
let r = def
|
|
180
|
-
let i = input
|
|
181
|
-
while (true) {
|
|
182
|
-
const result = next(i)
|
|
183
|
-
if (result === undefined) {
|
|
184
|
-
return r
|
|
185
|
-
}
|
|
186
|
-
r = result.first
|
|
187
|
-
i = result.tail
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/** @type {<D>(def: D) => <T>(f: (value: T) => boolean) => (sequence: Sequence<T>) => D|T} */
|
|
192
|
-
const find = def => f => input => first(def)(filter(f)(input))
|
|
193
|
-
|
|
194
|
-
/** @type {(value: boolean) => boolean} */
|
|
195
|
-
const boolIdentity = identity
|
|
196
|
-
|
|
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))
|
|
202
|
-
|
|
203
|
-
/** @type {<T>(value: T) => (sequence: Sequence<T>) => boolean} */
|
|
204
|
-
const includes = value => input => some(map(strictEqual(value))(input))
|
|
205
|
-
|
|
206
|
-
/** @type {(count: number) => Thunk<number>} */
|
|
207
|
-
const countdown = count => () => {
|
|
208
|
-
if (count <= 0) { return undefined }
|
|
209
|
-
const first = count - 1
|
|
210
|
-
return { first, tail: countdown(first) }
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* @template T,A
|
|
215
|
-
* @typedef {(value: T) => ScanState<T, A>} ScanOperator
|
|
216
|
-
*/
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* @template T,A
|
|
220
|
-
* @typedef {readonly[A, ScanOperator<T, A>]} ScanState
|
|
221
|
-
*/
|
|
222
|
-
|
|
223
|
-
/** @type {<T,A>(operator: ScanOperator<T, A>) => (result: ResultOne<T>) => Node<A>} */
|
|
224
|
-
const scanFn = operator => ({first, tail}) => {
|
|
225
|
-
const [value, nextOperator] = operator(first)
|
|
226
|
-
return { first: value, tail: scan(nextOperator)(tail) }
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/** @type {<T,A>(operator: ScanOperator<T, A>) => (input: Sequence<T>) => Thunk<A>} */
|
|
230
|
-
const scan = operator => apply(scanFn(operator))
|
|
231
|
-
|
|
232
|
-
/** @type {<T,A>(operator: ScanOperator<T, A>) => <D>(def: D)=> (input: Sequence<T>) => D|A} */
|
|
233
|
-
const scanReduce = operator => def => input => last(def)(scan(operator)(input))
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* @template T,A
|
|
237
|
-
* @typedef {(prior: A) => (value: T) => A} ReduceOperator
|
|
238
|
-
*/
|
|
239
|
-
|
|
240
|
-
/** @type {<T,A>(operator: ReduceOperator<T, A>) => (init: A) => ScanState<T, A>} */
|
|
241
|
-
const scanState = operator => init => [init, scanOperator(operator)(init)]
|
|
242
|
-
|
|
243
|
-
/** @type {<T,A>(operator: ReduceOperator<T, A>) => (init: A) => ScanOperator<T, A>} */
|
|
244
|
-
const scanOperator = operator => init => value => scanState(operator)(operator(init)(value))
|
|
245
|
-
|
|
246
|
-
/** @type {<T,A>(operator: ReduceOperator<T, A>) => (init: A) => (input: Sequence<T>) => A} */
|
|
247
|
-
const reduce = operator => init => scanReduce(scanOperator(operator)(init))(init)
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* @template T
|
|
251
|
-
* @typedef {ReduceOperator<T, T>} FoldOperator
|
|
252
|
-
*/
|
|
253
|
-
|
|
254
|
-
/** @type {<T>(operator: FoldOperator<T>) => <D>(def: D) => (input: Sequence<T>) => D|T} */
|
|
255
|
-
const fold = operator => def => scanReduce(scanState(operator))(def)
|
|
256
|
-
|
|
257
|
-
const sum = fold(addition)(0)
|
|
258
|
-
|
|
259
|
-
const min = fold(op.min)(undefined)
|
|
260
|
-
|
|
261
|
-
const max = fold(op.max)(undefined)
|
|
262
|
-
|
|
263
|
-
/** @type {(separator: string) => (input: Sequence<string>) => string} */
|
|
264
|
-
const join = separator => fold(op.join(separator))('')
|
|
265
|
-
|
|
266
|
-
/** @type {(a: number) => () => number} */
|
|
267
|
-
const counter = a => () => a + 1
|
|
268
|
-
|
|
269
|
-
/** @type {<T>(input: Sequence<T>) => number} */
|
|
270
|
-
const length = reduce(counter)(0)
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* @template T
|
|
274
|
-
* @typedef {readonly[number, T]} Entry
|
|
275
|
-
*/
|
|
276
|
-
|
|
277
|
-
/** @type {(index: number) => <T>(value: T) => ScanState<T, Entry<T>>} */
|
|
278
|
-
const entryOp = index => value => [[index, value], entryOp(index + 1)]
|
|
279
|
-
|
|
280
|
-
/** @type {<T>(input: Sequence<T>) => Thunk<Entry<T>>} */
|
|
281
|
-
const entries = scan(entryOp(0))
|
|
282
|
-
|
|
283
|
-
/** @type {<T>(prior: Sequence<T>) => (value: T) => Sequence<T>} */
|
|
284
|
-
const reverseOp = prior => value => sequence(value)(prior)
|
|
285
|
-
|
|
286
|
-
/** @type {<T>(input: Sequence<T>) => Sequence<T>} */
|
|
287
|
-
const reverse = reduce(reverseOp)(empty)
|
|
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
|
-
|
|
311
|
-
module.exports = {
|
|
312
|
-
/** @readonly */
|
|
313
|
-
sequence,
|
|
314
|
-
/** @readonly */
|
|
315
|
-
iterable,
|
|
316
|
-
/** @readonly */
|
|
317
|
-
next,
|
|
318
|
-
/** @readonly */
|
|
319
|
-
toArray,
|
|
320
|
-
/** @readonly */
|
|
321
|
-
flat,
|
|
322
|
-
/** @readonly */
|
|
323
|
-
last,
|
|
324
|
-
/** @readonly */
|
|
325
|
-
concat,
|
|
326
|
-
/** @readonly */
|
|
327
|
-
first,
|
|
328
|
-
/** @readonly */
|
|
329
|
-
map,
|
|
330
|
-
/** @readonly */
|
|
331
|
-
flatMap,
|
|
332
|
-
/** @readonly */
|
|
333
|
-
filter,
|
|
334
|
-
/** @readonly */
|
|
335
|
-
filterMap,
|
|
336
|
-
/** @readonly */
|
|
337
|
-
find,
|
|
338
|
-
/** @readonly */
|
|
339
|
-
some,
|
|
340
|
-
/** @readonly */
|
|
341
|
-
every,
|
|
342
|
-
/** @readonly */
|
|
343
|
-
includes,
|
|
344
|
-
/** @readonly */
|
|
345
|
-
takeWhile,
|
|
346
|
-
/** @readonly */
|
|
347
|
-
take,
|
|
348
|
-
/** @readonly */
|
|
349
|
-
dropWhile,
|
|
350
|
-
/** @readonly */
|
|
351
|
-
drop,
|
|
352
|
-
/** @readonly */
|
|
353
|
-
scanOperator,
|
|
354
|
-
/** @readonly */
|
|
355
|
-
scanState,
|
|
356
|
-
/** @readonly */
|
|
357
|
-
scan,
|
|
358
|
-
/** @readonly */
|
|
359
|
-
reduce,
|
|
360
|
-
/** @readonly */
|
|
361
|
-
fold,
|
|
362
|
-
/** @readonly */
|
|
363
|
-
sum,
|
|
364
|
-
/** @readonly */
|
|
365
|
-
min,
|
|
366
|
-
/** @readonly */
|
|
367
|
-
max,
|
|
368
|
-
/** @readonly */
|
|
369
|
-
join,
|
|
370
|
-
/** @readonly */
|
|
371
|
-
entries,
|
|
372
|
-
/** @readonly */
|
|
373
|
-
length,
|
|
374
|
-
/** @readonly */
|
|
375
|
-
reverse,
|
|
376
|
-
/** @readonly */
|
|
377
|
-
zip,
|
|
378
|
-
/** @readonly */
|
|
379
|
-
equal,
|
|
380
|
-
/** @readonly */
|
|
381
|
-
countdown,
|
|
382
|
-
}
|