functionalscript 0.0.220 → 0.0.222
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/package.json +1 -1
- package/sequence/index.js +43 -31
- package/sequence/test.js +1 -1
package/package.json
CHANGED
package/sequence/index.js
CHANGED
|
@@ -24,7 +24,12 @@ const op = require('../function/operator')
|
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* @template T
|
|
27
|
-
* @typedef { undefined |
|
|
27
|
+
* @typedef { undefined | ResultOne<T> } Result
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @template T
|
|
32
|
+
* @typedef {{ readonly first: T, readonly tail: Sequence<T> }} ResultOne
|
|
28
33
|
*/
|
|
29
34
|
|
|
30
35
|
const empty = () => undefined
|
|
@@ -73,15 +78,11 @@ const iterable = sequence => ({
|
|
|
73
78
|
let i = sequence
|
|
74
79
|
while (true) {
|
|
75
80
|
if (i instanceof Array) { return yield *i }
|
|
76
|
-
const n =
|
|
81
|
+
const n = next(i)
|
|
77
82
|
if (n === undefined) { return }
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const { first, tail } = n
|
|
82
|
-
yield first
|
|
83
|
-
i = tail
|
|
84
|
-
}
|
|
83
|
+
const { first, tail } = n
|
|
84
|
+
yield first
|
|
85
|
+
i = tail
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
88
|
})
|
|
@@ -92,47 +93,50 @@ const toArray = sequence => {
|
|
|
92
93
|
return Array.from(iterable(sequence))
|
|
93
94
|
}
|
|
94
95
|
|
|
95
|
-
/** @type {<
|
|
96
|
-
const
|
|
97
|
-
const n = next(
|
|
96
|
+
/** @type {<I, O>(f: (result: ResultOne<I>) => Node<O>) => (input: Sequence<I>) => Thunk<O>} */
|
|
97
|
+
const nextMap = f => input => () => {
|
|
98
|
+
const n = next(input)
|
|
98
99
|
if (n === undefined) { return undefined }
|
|
99
|
-
|
|
100
|
-
return [first, flat(tail)]
|
|
100
|
+
return f(n)
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
/** @type {<T>(result: ResultOne<Sequence<T>>) => Node<T>} */
|
|
104
|
+
const flatFn = ({first, tail}) => [first, flat(tail)]
|
|
105
|
+
|
|
106
|
+
/** @type {<T>(sequence: Sequence<Sequence<T>>) => Thunk<T>} */
|
|
107
|
+
const flat = nextMap(flatFn)
|
|
108
|
+
|
|
103
109
|
/** @type {<T>(...array: readonly Sequence<T>[]) => Thunk<T>} */
|
|
104
110
|
const concat = (...array) => flat(array)
|
|
105
111
|
|
|
112
|
+
/** @type {<I, O>(f: (value: I) => O) => (result: ResultOne<I>) => Node<O>} */
|
|
113
|
+
const mapFn = f => ({ first, tail }) => ({ first: f(first), tail: map(f)(tail) })
|
|
114
|
+
|
|
106
115
|
/** @type {<I, O>(f: (value: I) => O) => (input: Sequence<I>) => Thunk<O>} */
|
|
107
|
-
const map = f =>
|
|
108
|
-
const n = next(sequence)
|
|
109
|
-
if (n === undefined) { return undefined }
|
|
110
|
-
const { first, tail } = n
|
|
111
|
-
return { first: f(first), tail: map(f)(tail) }
|
|
112
|
-
}
|
|
116
|
+
const map = f => nextMap(mapFn(f))
|
|
113
117
|
|
|
114
118
|
/** @type {<I, O>(f: (value: I) => Sequence<O>) => (input: Sequence<I>) => Thunk<O>} */
|
|
115
|
-
const flatMap = f =>
|
|
119
|
+
const flatMap = f => compose(map(f))(flat)
|
|
116
120
|
|
|
117
|
-
/** @type {<T>(f: (value: T) => boolean) => (
|
|
118
|
-
const
|
|
119
|
-
const n = next(sequence)
|
|
120
|
-
if (n === undefined) { return undefined }
|
|
121
|
-
const { first, tail } = n
|
|
121
|
+
/** @type {<T>(f: (value: T) => boolean) => (result: ResultOne<T>) => Node<T>} */
|
|
122
|
+
const filterFn = f => ({ first, tail }) => {
|
|
122
123
|
const fTail = filter(f)(tail)
|
|
123
124
|
return f(first) ? { first, tail: fTail } : fTail()
|
|
124
125
|
}
|
|
125
126
|
|
|
126
|
-
/** @type {<
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
127
|
+
/** @type {<T>(f: (value: T) => boolean) => (input: Sequence<T>) => Thunk<T>} */
|
|
128
|
+
const filter = f => nextMap(filterFn(f))
|
|
129
|
+
|
|
130
|
+
/** @type {<I, O>(f: (value: I) => O|undefined) => (result: ResultOne<I>) => Node<O>} */
|
|
131
|
+
const filterMapFn = f => ({first, tail}) => {
|
|
131
132
|
const fFirst = f(first)
|
|
132
133
|
const fTail = filterMap(f)(tail)
|
|
133
134
|
return fFirst === undefined ? fTail() : { first: fFirst, tail: fTail }
|
|
134
135
|
}
|
|
135
136
|
|
|
137
|
+
/** @type {<I, O>(f: (value: I) => O|undefined) => (input: Sequence<I>) => Thunk<O>} */
|
|
138
|
+
const filterMap = f => nextMap(filterMapFn(f))
|
|
139
|
+
|
|
136
140
|
/** @type {<T>(f: (value: T) => boolean) => (input: Sequence<T>) => Thunk<T>} */
|
|
137
141
|
const takeWhile = f => input => () => {
|
|
138
142
|
const result = next(input)
|
|
@@ -248,6 +252,12 @@ const sum = fold(addition)(0)
|
|
|
248
252
|
/** @type {(separator: string) => (input: Sequence<string>) => string} */
|
|
249
253
|
const join = separator => fold(op.join(separator))('')
|
|
250
254
|
|
|
255
|
+
/** @type {(a: number) => () => number} */
|
|
256
|
+
const counter = a => () => a + 1
|
|
257
|
+
|
|
258
|
+
/** @type {<T>(input: Sequence<T>) => number} */
|
|
259
|
+
const length = reduce(counter)(0)
|
|
260
|
+
|
|
251
261
|
/**
|
|
252
262
|
* @template T
|
|
253
263
|
* @typedef {readonly[number, T]} Entry
|
|
@@ -311,5 +321,7 @@ module.exports = {
|
|
|
311
321
|
/** @readonly */
|
|
312
322
|
entries,
|
|
313
323
|
/** @readonly */
|
|
324
|
+
length,
|
|
325
|
+
/** @readonly */
|
|
314
326
|
countdown,
|
|
315
327
|
}
|