functionalscript 0.0.181 → 0.0.182
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/README.md +3 -0
- package/btree/index.js +1 -1
- package/btree/test.js +2 -2
- package/package.json +1 -1
- package/sequence/list/index.js +26 -25
- package/sequence/list/test.js +3 -3
package/README.md
CHANGED
|
@@ -10,6 +10,9 @@ Try FunctionalScript [here](https://functionalscript.com/).
|
|
|
10
10
|
|
|
11
11
|
Create a new FunctionalScript repository on GitHub [here](https://github.com/functionalscript/template/generate).
|
|
12
12
|
|
|
13
|
+
One of the main challenges is how to make a pure functional language when ES6 TCO is not supported by Chrome and Firefox.
|
|
14
|
+
A workaround for this problem is to use `let` for renaming objects.
|
|
15
|
+
|
|
13
16
|
## JSON
|
|
14
17
|
|
|
15
18
|
```js
|
package/btree/index.js
CHANGED
package/btree/test.js
CHANGED
|
@@ -22,11 +22,11 @@ const test = () => {
|
|
|
22
22
|
//
|
|
23
23
|
{
|
|
24
24
|
/** @type {import('../sequence/list').Result<string>} */
|
|
25
|
-
let result = list.
|
|
25
|
+
let result = list.next(valuesList(node))
|
|
26
26
|
while (result !== undefined) {
|
|
27
27
|
const t = result[0]
|
|
28
28
|
console.log(t)
|
|
29
|
-
result = list.
|
|
29
|
+
result = list.next(result[1])
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
}
|
package/package.json
CHANGED
package/sequence/list/index.js
CHANGED
|
@@ -10,17 +10,19 @@ const { todo } = require('../../dev')
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
* We need this workaround because modern JavaScript implementations
|
|
14
|
-
* don't support ES6 TCO (Tail Call Optimization)
|
|
15
|
-
*
|
|
16
|
-
* Without this wotkaround we may have a stack overflow if a list
|
|
17
|
-
* contains a lot of concateneted lists.
|
|
18
|
-
*
|
|
19
13
|
* @template T
|
|
20
14
|
* @typedef {readonly [List<T>, List<T>]} Concat
|
|
21
15
|
*/
|
|
22
16
|
|
|
23
17
|
/**
|
|
18
|
+
* Please note that the list also contains `Concat<T>. We need this as
|
|
19
|
+
* a workaround because modern JavaScript implementations don't support
|
|
20
|
+
* ES6 TCO (Tail Call Optimization).
|
|
21
|
+
*
|
|
22
|
+
* Without this wotkaround we may have a stack overflow if a list
|
|
23
|
+
* contains a lot of concateneted lists. Use `next` function to extract
|
|
24
|
+
* a list.
|
|
25
|
+
*
|
|
24
26
|
* @template T
|
|
25
27
|
* @typedef { ListFunc<T> | Concat<T>} List
|
|
26
28
|
*/
|
|
@@ -41,7 +43,7 @@ const empty = () => undefined
|
|
|
41
43
|
const norm = ([a0, a1]) => b => [a0, [a1, b]]
|
|
42
44
|
|
|
43
45
|
/** @type {<T>(list: List<T>) => Result<T>} */
|
|
44
|
-
const
|
|
46
|
+
const next = list => {
|
|
45
47
|
let i = list
|
|
46
48
|
while (true) {
|
|
47
49
|
if (typeof i === 'function') { return i() }
|
|
@@ -86,10 +88,10 @@ const concat = a => b => [a, b]
|
|
|
86
88
|
const flatMap = f => input => () => {
|
|
87
89
|
let i = input
|
|
88
90
|
while (true) {
|
|
89
|
-
const result =
|
|
91
|
+
const result = next(i)
|
|
90
92
|
if (result === undefined) { return undefined }
|
|
91
93
|
const [first, tail] = result
|
|
92
|
-
const firstResult =
|
|
94
|
+
const firstResult = next(f(first))
|
|
93
95
|
if (firstResult !== undefined) {
|
|
94
96
|
const [firstFirst, firstTail] = firstResult
|
|
95
97
|
return [firstFirst, concat(firstTail)(flatMap(f)(tail))]
|
|
@@ -109,15 +111,13 @@ const filter = f => flatMap(i => f(i) ? one(i) : empty)
|
|
|
109
111
|
|
|
110
112
|
/** @type {<T, R>(s: base.Scan<T, R>) => ListMap<T, R>} */
|
|
111
113
|
const scan = s => input => () => {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
/** @type {(firstAndTail: FirstAndTail<T>) => Result<R>} */
|
|
116
|
-
const defined = ([first, tail]) => {
|
|
117
|
-
const [newFirst, newS] = s(first)
|
|
118
|
-
return [newFirst, scan(newS)(tail)]
|
|
114
|
+
const result = next(input)
|
|
115
|
+
if (result === undefined) {
|
|
116
|
+
return result
|
|
119
117
|
}
|
|
120
|
-
|
|
118
|
+
const [first, tail] = result
|
|
119
|
+
const [newFirst, newS] = s(first)
|
|
120
|
+
return [newFirst, scan(newS)(tail)]
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
/** @type {<T, R>(s: base.InclusiveScan<T, R>) => ListMap<T, R>} */
|
|
@@ -128,7 +128,7 @@ const last = def => input => {
|
|
|
128
128
|
let r = def
|
|
129
129
|
let i = input
|
|
130
130
|
while (true) {
|
|
131
|
-
const result =
|
|
131
|
+
const result = next(i)
|
|
132
132
|
if (result === undefined) {
|
|
133
133
|
return r
|
|
134
134
|
}
|
|
@@ -151,17 +151,16 @@ const join = pipe(base.join)(reduce)
|
|
|
151
151
|
|
|
152
152
|
/** @type {<T>(f: (value: T) => boolean) => ListMap<T, T>} */
|
|
153
153
|
const takeWhile = f => input => () => {
|
|
154
|
-
const result =
|
|
154
|
+
const result = next(input)
|
|
155
155
|
if (result === undefined || !f(result[0])) { return undefined }
|
|
156
156
|
return result
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
/** @type {<T>(f: (value: T) => boolean) => (input: List<T>) => T|undefined} */
|
|
160
160
|
const find = f => input => {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
return option.map(defined)(get(filter(f)(input)))
|
|
161
|
+
const result = next(filter(f)(input))
|
|
162
|
+
if (result === undefined) { return undefined }
|
|
163
|
+
return result[0]
|
|
165
164
|
}
|
|
166
165
|
|
|
167
166
|
/**
|
|
@@ -172,7 +171,7 @@ const iterable = list => ({
|
|
|
172
171
|
*[Symbol.iterator]() {
|
|
173
172
|
let i = list
|
|
174
173
|
while (true) {
|
|
175
|
-
const result =
|
|
174
|
+
const result = next(i)
|
|
176
175
|
if (result === undefined) { return }
|
|
177
176
|
yield result[0]
|
|
178
177
|
i = result[1]
|
|
@@ -182,7 +181,7 @@ const iterable = list => ({
|
|
|
182
181
|
|
|
183
182
|
module.exports = {
|
|
184
183
|
/** @readonly */
|
|
185
|
-
|
|
184
|
+
next,
|
|
186
185
|
/** @readonly */
|
|
187
186
|
one,
|
|
188
187
|
/** @readonly */
|
|
@@ -219,4 +218,6 @@ module.exports = {
|
|
|
219
218
|
length,
|
|
220
219
|
/** @readonly */
|
|
221
220
|
find,
|
|
221
|
+
/** @readonly */
|
|
222
|
+
takeWhile,
|
|
222
223
|
}
|
package/sequence/list/test.js
CHANGED
|
@@ -5,7 +5,7 @@ const { sum } = require('..')
|
|
|
5
5
|
const print = a => {
|
|
6
6
|
let i = a
|
|
7
7
|
while (true) {
|
|
8
|
-
const result = list.
|
|
8
|
+
const result = list.next(i)
|
|
9
9
|
if (result === undefined) { return }
|
|
10
10
|
console.log(result[0])
|
|
11
11
|
i = result[1]
|
|
@@ -24,7 +24,7 @@ const print = a => {
|
|
|
24
24
|
for (let i = 0; i < 1_000_000; ++i) {
|
|
25
25
|
x = list.concat(list.empty)(x)
|
|
26
26
|
}
|
|
27
|
-
const r = list.
|
|
27
|
+
const r = list.next(x)
|
|
28
28
|
print(x)
|
|
29
29
|
}
|
|
30
30
|
{
|
|
@@ -32,7 +32,7 @@ const print = a => {
|
|
|
32
32
|
for (let i = 0; i < 1_000_000; ++i) {
|
|
33
33
|
x = list.concat(x)(list.one(i))
|
|
34
34
|
}
|
|
35
|
-
const r = list.
|
|
35
|
+
const r = list.next(x)
|
|
36
36
|
// print(x)
|
|
37
37
|
}
|
|
38
38
|
}
|