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
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Common.js
|
|
2
|
+
|
|
3
|
+
```ts
|
|
4
|
+
// package/index.js
|
|
5
|
+
|
|
6
|
+
type PackageGet = (packageId: string) => Package | undefined
|
|
7
|
+
type Package = {
|
|
8
|
+
// returns a global package id.
|
|
9
|
+
readonly dependency: (localPackageId: string) => string | undefined
|
|
10
|
+
// returns source of the file.
|
|
11
|
+
readonly file: (localFileId: string) => string | undefined
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// module/index.js
|
|
15
|
+
|
|
16
|
+
type ModuleMapInterface<M> = {
|
|
17
|
+
readonly at: (moduleId: string) => (moduleMap: M) => ModuleState | undefined
|
|
18
|
+
readonly insert: (moduleId: string) => (moduleState: ModuleState) => (moduleMap: M) => M
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type ModuleState = readonly['ok', Module] | readonly['error', ModuleError] | readonly['building']
|
|
22
|
+
|
|
23
|
+
type Module = {
|
|
24
|
+
readonly exports: unknown
|
|
25
|
+
readonly requireMap: object.Map<string>
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
type ModuleError = 'file not found' | 'compile error' | 'runtime error' | 'circular reference'
|
|
29
|
+
|
|
30
|
+
type ModuleId = {
|
|
31
|
+
readonly packageId: string,
|
|
32
|
+
readonly path: readonly string[],
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const moduleIdToString: (moduleId: ModuleId) => string;
|
|
36
|
+
|
|
37
|
+
// build/index.js
|
|
38
|
+
|
|
39
|
+
type BuildConfig<M> = {
|
|
40
|
+
readonly packageGet: PackageGet
|
|
41
|
+
readonly moduleMapInterface: ModuleMapInterface<M>
|
|
42
|
+
readonly moduleId: ModuleId
|
|
43
|
+
readonly moduleMap: M // mutable
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
type BuildState<M> = {
|
|
47
|
+
readonly packageGet: PackageGet
|
|
48
|
+
readonly moduleMapInterface: ModuleMapInterface<M>
|
|
49
|
+
readonly moduleId: ModuleId
|
|
50
|
+
readonly moduleMap: M // mutable
|
|
51
|
+
readonly ModuleRequireMap: map.Map<string> // mutable
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const getOrBuild: <M>(buildConfig: BuildConfig<M>) => readonly[ModuleState, M];
|
|
55
|
+
```
|
package/commonjs/module/index.js
CHANGED
|
@@ -1,22 +1,35 @@
|
|
|
1
|
-
const map = require('../../types/map')
|
|
2
1
|
const object = require('../../types/object')
|
|
3
|
-
const run = require('../run')
|
|
4
|
-
const seq = require('../../types/sequence')
|
|
5
2
|
|
|
6
3
|
/**
|
|
4
|
+
* @template M
|
|
7
5
|
* @typedef {{
|
|
8
|
-
* readonly
|
|
9
|
-
* readonly
|
|
10
|
-
* }}
|
|
6
|
+
* readonly at: (moduleId: string) => (moduleMap: M) => ModuleState | undefined
|
|
7
|
+
* readonly insert: (moduleId: string) => (moduleState: ModuleState) => (moduleMap: M) => M
|
|
8
|
+
* }} ModuleMapInterface
|
|
11
9
|
*/
|
|
12
10
|
|
|
13
11
|
/**
|
|
12
|
+
* @typedef {|
|
|
13
|
+
* readonly['ok', Module] |
|
|
14
|
+
* readonly['error', ModuleError] |
|
|
15
|
+
* readonly['building']
|
|
16
|
+
* } ModuleState
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
14
20
|
* @typedef {{
|
|
15
|
-
* readonly
|
|
16
|
-
* readonly
|
|
17
|
-
* }}
|
|
21
|
+
* readonly exports: unknown
|
|
22
|
+
* readonly requireMap: object.Map<string>
|
|
23
|
+
* }} Module
|
|
18
24
|
*/
|
|
19
25
|
|
|
20
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* @typedef {|
|
|
28
|
+
* 'file not found' |
|
|
29
|
+
* 'compile error' |
|
|
30
|
+
* 'runtime error' |
|
|
31
|
+
* 'circular reference'
|
|
32
|
+
* } ModuleError
|
|
33
|
+
*/
|
|
21
34
|
|
|
22
35
|
module.exports = {}
|
|
@@ -20,9 +20,14 @@ const isPackageJson = j => {
|
|
|
20
20
|
return true
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {{
|
|
25
|
+
* readonly dependency: (localPackageId: string) => string | undefined
|
|
26
|
+
* readonly file: (localFileId: string) => string | undefined
|
|
27
|
+
* }} Package
|
|
28
|
+
*/
|
|
24
29
|
|
|
25
|
-
/** @typedef {
|
|
30
|
+
/** @typedef {(packageId: string) => Package | undefined} PackageGet */
|
|
26
31
|
|
|
27
32
|
module.exports = {
|
|
28
33
|
/** @readonly */
|
package/commonjs/path/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
const seq = require("../../types/
|
|
1
|
+
const seq = require("../../types/list")
|
|
2
2
|
const option = require("../../types/option")
|
|
3
3
|
const { compose } = require("../../types/function")
|
|
4
4
|
const dep = require("../package/dependencies")
|
|
5
5
|
const { at } = require("../../types/object")
|
|
6
|
-
const pack = require("../package")
|
|
6
|
+
// const pack = require("../package")
|
|
7
7
|
|
|
8
8
|
/** @typedef {readonly string[]} Items */
|
|
9
9
|
|
|
@@ -18,7 +18,7 @@ const pack = require("../package")
|
|
|
18
18
|
/** @type {(path: string) => readonly string[]} */
|
|
19
19
|
const split = path => path.split('/')
|
|
20
20
|
|
|
21
|
-
/** @type {(s: undefined|seq.
|
|
21
|
+
/** @type {(s: undefined|seq.List<string>) => (items: string) => undefined|seq.List<string>} */
|
|
22
22
|
const normItemsOp = prior => item => {
|
|
23
23
|
if (prior === undefined) { return undefined }
|
|
24
24
|
switch (item) {
|
|
@@ -29,17 +29,17 @@ const normItemsOp = prior => item => {
|
|
|
29
29
|
return result.tail
|
|
30
30
|
}
|
|
31
31
|
default: {
|
|
32
|
-
return seq.
|
|
32
|
+
return seq.nonEmpty(item)(prior)
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
/** @type {(items: seq.
|
|
37
|
+
/** @type {(items: seq.List<string>) => seq.List<string>|undefined} */
|
|
38
38
|
const normItems = compose(seq.reduce(normItemsOp)([]))(option.map(seq.reverse))
|
|
39
39
|
|
|
40
40
|
/** @type {(local: string) => (path: string) => LocalPath|undefined} */
|
|
41
41
|
const parseLocal = local => {
|
|
42
|
-
/** @type {(path: string) => readonly[boolean, seq.
|
|
42
|
+
/** @type {(path: string) => readonly[boolean, seq.List<string>]} */
|
|
43
43
|
const fSeq = path => {
|
|
44
44
|
const pathSeq = split(path)
|
|
45
45
|
switch (seq.first(undefined)(pathSeq)) {
|
|
@@ -61,9 +61,9 @@ const parseLocal = local => {
|
|
|
61
61
|
return f
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
/** @typedef {readonly[string, seq.
|
|
64
|
+
/** @typedef {readonly[string, seq.List<string>]} IdPath */
|
|
65
65
|
|
|
66
|
-
/** @type {(prior: readonly[string|undefined, seq.
|
|
66
|
+
/** @type {(prior: readonly[string|undefined, seq.List<string>]) => seq.Thunk<IdPath>} */
|
|
67
67
|
const variants = prior => () => {
|
|
68
68
|
const [a, b] = prior
|
|
69
69
|
const r = seq.next(b)
|
|
@@ -88,7 +88,7 @@ const mapDependency = d => ([external, internal]) => {
|
|
|
88
88
|
* }} Path
|
|
89
89
|
*/
|
|
90
90
|
|
|
91
|
-
/** @type {(d: dep.DependenciesJson) => (dir: boolean) => (items: seq.
|
|
91
|
+
/** @type {(d: dep.DependenciesJson) => (dir: boolean) => (items: seq.List<string>) => Path|undefined} */
|
|
92
92
|
const parseGlobal = d => dir => items => {
|
|
93
93
|
if (d === undefined) { return undefined }
|
|
94
94
|
const v = variants([undefined, items])
|
package/commonjs/run/index.js
CHANGED
|
@@ -9,7 +9,7 @@ const result = require('../../types/result')
|
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* @template T
|
|
12
|
-
* @typedef {(
|
|
12
|
+
* @typedef {(path: string) => (prior: T) => ModuleResult<T>} Require
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
/** @typedef {(source: string) => result.Result<Module, unknown>} Compile */
|
package/io/commonjs/index.js
CHANGED
|
@@ -6,7 +6,7 @@ const run = require('../../commonjs/run')
|
|
|
6
6
|
const build = f => immutableRequire => mutableData => {
|
|
7
7
|
/** @type {(path: string) => unknown} */
|
|
8
8
|
const mutableRequire = path => {
|
|
9
|
-
const [result, data] = immutableRequire(
|
|
9
|
+
const [result, data] = immutableRequire(path)(mutableData)
|
|
10
10
|
mutableData = data
|
|
11
11
|
return unwrap(result)
|
|
12
12
|
}
|
package/io/commonjs/test.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const cp = require('child_process')
|
|
2
2
|
const fs = require('fs')
|
|
3
|
-
const
|
|
4
|
-
const { isPackageJson } = require('../../../commonjs/package')
|
|
3
|
+
const package_json = require('../../../package.json')
|
|
5
4
|
|
|
6
5
|
const b =cp.execSync('git log --oneline')
|
|
7
6
|
|
|
@@ -11,10 +10,6 @@ const v = `0.0.${r}`
|
|
|
11
10
|
|
|
12
11
|
console.log(`version: ${v}`)
|
|
13
12
|
|
|
14
|
-
const package_json = json.parse(fs.readFileSync('package.json').toString())
|
|
15
|
-
|
|
16
|
-
if (!isPackageJson(package_json)) { throw 'error' }
|
|
17
|
-
|
|
18
13
|
const x = { ...package_json, version: v }
|
|
19
14
|
|
|
20
15
|
fs.writeFileSync('package.json', JSON.stringify(x, null, 2))
|
package/json/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
const seq = require('../types/
|
|
1
|
+
const seq = require('../types/list')
|
|
2
2
|
const object = require('../types/object')
|
|
3
3
|
const array = require('../types/array')
|
|
4
|
-
const
|
|
4
|
+
const op = require('../types/function/operator')
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @typedef {{
|
|
@@ -13,9 +13,9 @@ const { todo } = require('../dev')
|
|
|
13
13
|
|
|
14
14
|
/** @typedef {Object|boolean|string|number|null|Array} Unknown */
|
|
15
15
|
|
|
16
|
-
/** @type {(value: Unknown) => (path: seq.
|
|
16
|
+
/** @type {(value: Unknown) => (path: seq.List<string>) => (src: Unknown|undefined) => Unknown} */
|
|
17
17
|
const setProperty = value => {
|
|
18
|
-
/** @type {(path: seq.
|
|
18
|
+
/** @type {(path: seq.List<string>) => (src: Unknown|undefined) => Unknown} */
|
|
19
19
|
const f = path => src => {
|
|
20
20
|
const result = seq.next(path)
|
|
21
21
|
if (result === undefined) { return value }
|
|
@@ -26,10 +26,10 @@ const setProperty = value => {
|
|
|
26
26
|
return f
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
/** @type {(_: string) => seq.
|
|
29
|
+
/** @type {(_: string) => seq.List<string>} */
|
|
30
30
|
const stringSerialize = input => [JSON.stringify(input)]
|
|
31
31
|
|
|
32
|
-
/** @type {(_: number) => seq.
|
|
32
|
+
/** @type {(_: number) => seq.List<string>} */
|
|
33
33
|
const numberSerialize = input => [JSON.stringify(input)]
|
|
34
34
|
|
|
35
35
|
const nullSerialize = ['null']
|
|
@@ -38,19 +38,19 @@ const trueSerialize = ['true']
|
|
|
38
38
|
|
|
39
39
|
const falseSerialize = ['false']
|
|
40
40
|
|
|
41
|
-
/** @type {(_: boolean) => seq.
|
|
41
|
+
/** @type {(_: boolean) => seq.List<string>} */
|
|
42
42
|
const boolSerialize = value => value ? trueSerialize : falseSerialize
|
|
43
43
|
|
|
44
44
|
const colon = [':']
|
|
45
45
|
const comma = [',']
|
|
46
46
|
|
|
47
|
-
/** @type {
|
|
47
|
+
/** @type {op.Fold<seq.List<string>>} */
|
|
48
48
|
const joinOp = a => b => seq.flat([a, comma, b])
|
|
49
49
|
|
|
50
|
-
/** @type {(input: seq.
|
|
50
|
+
/** @type {(input: seq.List<seq.List<string>>) => seq.List<string>} */
|
|
51
51
|
const join = seq.fold(joinOp)([])
|
|
52
52
|
|
|
53
|
-
/** @type {(open: string) => (close: string) => (input: seq.
|
|
53
|
+
/** @type {(open: string) => (close: string) => (input: seq.List<seq.List<string>>) => seq.List<string>} */
|
|
54
54
|
const list = open => close => {
|
|
55
55
|
const seqOpen = [open]
|
|
56
56
|
const seqClose = [close]
|
|
@@ -63,19 +63,19 @@ const arrayList = list('[')(']')
|
|
|
63
63
|
|
|
64
64
|
/** @typedef {object.Entry<Unknown>} Entry*/
|
|
65
65
|
|
|
66
|
-
/** @typedef {(seq.
|
|
66
|
+
/** @typedef {(seq.List<Entry>)} Entries */
|
|
67
67
|
|
|
68
68
|
/** @typedef {(entries: Entries) => Entries} MapEntries */
|
|
69
69
|
|
|
70
|
-
/** @type {(mapEntries: MapEntries) => (value: Unknown) => seq.
|
|
70
|
+
/** @type {(mapEntries: MapEntries) => (value: Unknown) => seq.List<string>} */
|
|
71
71
|
const serialize = sort => {
|
|
72
|
-
/** @type {(kv: readonly[string, Unknown]) => seq.
|
|
72
|
+
/** @type {(kv: readonly[string, Unknown]) => seq.List<string>} */
|
|
73
73
|
const propertySerialize = ([k, v]) => seq.flat([
|
|
74
74
|
stringSerialize(k),
|
|
75
75
|
colon,
|
|
76
76
|
f(v)
|
|
77
77
|
])
|
|
78
|
-
/** @type {(object: Object) => seq.
|
|
78
|
+
/** @type {(object: Object) => seq.List<string>} */
|
|
79
79
|
const objectSerialize = input => {
|
|
80
80
|
const entries = Object.entries(input)
|
|
81
81
|
const sortedEntries = sort(entries)
|
|
@@ -83,12 +83,12 @@ const serialize = sort => {
|
|
|
83
83
|
const serializedEntries = seq.map(propertySerialize)(sortedEntries)
|
|
84
84
|
return objectList(serializedEntries)
|
|
85
85
|
}
|
|
86
|
-
/** @type {(input: Array) => seq.
|
|
86
|
+
/** @type {(input: Array) => seq.List<string>} */
|
|
87
87
|
const arraySerialize = input => {
|
|
88
88
|
const serializedEntries = seq.map(f)(input)
|
|
89
89
|
return arrayList(serializedEntries)
|
|
90
90
|
}
|
|
91
|
-
/** @type {(value: Unknown) => seq.
|
|
91
|
+
/** @type {(value: Unknown) => seq.List < string >} */
|
|
92
92
|
const f = value => {
|
|
93
93
|
switch (typeof value) {
|
|
94
94
|
case 'boolean': { return boolSerialize(value) }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "functionalscript",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.242",
|
|
4
4
|
"description": "FunctionalScript is a functional subset of JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -14,12 +14,19 @@
|
|
|
14
14
|
},
|
|
15
15
|
"author": "Natfoam",
|
|
16
16
|
"license": "Apache-2.0",
|
|
17
|
+
"keywords": [
|
|
18
|
+
"lambda",
|
|
19
|
+
"functional-programming",
|
|
20
|
+
"closure",
|
|
21
|
+
"pure-functional",
|
|
22
|
+
"typescript"
|
|
23
|
+
],
|
|
17
24
|
"bugs": {
|
|
18
25
|
"url": "https://github.com/functionalscript/functionalscript/issues"
|
|
19
26
|
},
|
|
20
27
|
"homepage": "https://github.com/functionalscript/functionalscript#readme",
|
|
21
28
|
"devDependencies": {
|
|
22
|
-
"@types/node": "^16.11.
|
|
29
|
+
"@types/node": "^16.11.12",
|
|
23
30
|
"typescript": "^4.5.2"
|
|
24
31
|
}
|
|
25
32
|
}
|
package/test.js
CHANGED
package/tsconfig.json
CHANGED
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
// "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
|
|
34
34
|
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
|
35
35
|
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
|
36
|
-
|
|
36
|
+
"resolveJsonModule": true, /* Enable importing .json files */
|
|
37
37
|
// "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */
|
|
38
38
|
|
|
39
39
|
/* JavaScript Support */
|
package/types/array/index.js
CHANGED
package/types/btree/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const cmp = require('../function/compare')
|
|
2
2
|
const { index3, index5 } = cmp
|
|
3
|
-
const seq = require('../
|
|
3
|
+
const seq = require('../list')
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @template T
|
|
@@ -129,41 +129,39 @@ const seq = require('../sequence')
|
|
|
129
129
|
const split = ([n0, v1, n2, v3, n4, v5, n6]) => [[n0, v1, n2], v3, [n4, v5, n6]]
|
|
130
130
|
|
|
131
131
|
/**
|
|
132
|
-
* @type {<T>(
|
|
132
|
+
* @type {<T>(extend: (o: Branch3<T>) => Result<T>) =>
|
|
133
133
|
* (replace: (r: Node<T>) => Node<T>) =>
|
|
134
134
|
* (result: Result<T>) =>
|
|
135
135
|
* Result<T>}
|
|
136
136
|
*/
|
|
137
|
-
const merge =
|
|
137
|
+
const merge = extend => replace => result => {
|
|
138
138
|
switch (result[0]) {
|
|
139
139
|
case 'done': { return result }
|
|
140
140
|
case 'replace': { return ['replace', replace(result[1])] }
|
|
141
|
-
default: { return
|
|
141
|
+
default: { return extend(result[1]) }
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
/**
|
|
146
|
-
* @type {<T>(overflow: (o: Branch3<T>) => Branch5<T>) =>
|
|
147
|
-
* (replace: (r: Node<T>) => Branch3<T>) =>
|
|
148
|
-
* (result: Result<T>) =>
|
|
149
|
-
* Result<T>}
|
|
150
|
-
*/
|
|
151
|
-
const merge2 = overflow => merge(o => ['replace', overflow(o)])
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* @type {<T>(overflow: (o: Branch3<T>) => Branch7<T>) =>
|
|
155
|
-
* (replace: (r: Node<T>) => Branch5<T>) =>
|
|
156
|
-
* (result: Result<T>) =>
|
|
157
|
-
* Result<T>}
|
|
158
|
-
*/
|
|
159
|
-
const merge3 = overflow => merge(o => ['overflow', split(overflow(o))])
|
|
160
|
-
|
|
161
145
|
/** @type {(visitor: Visitor) => <T>(cmp: Cmp<T>) => (init: Lazy<T>) => (node: Node<T>) => Result<T>} */
|
|
162
146
|
const visit = ({ found, notFound }) => cmp => {
|
|
163
147
|
const i3 = index3(cmp)
|
|
164
148
|
const i5 = index5(cmp)
|
|
149
|
+
/** @typedef {typeof cmp extends Cmp<infer T> ? T : never} T */
|
|
150
|
+
/**
|
|
151
|
+
* @type {(extend: (o: Branch3<T>) => Branch5<T>) =>
|
|
152
|
+
* (replace: (r: Node<T>) => Branch3<T>) =>
|
|
153
|
+
* (result: Result<T>) =>
|
|
154
|
+
* Result<T>}
|
|
155
|
+
*/
|
|
156
|
+
const merge2 = extend => merge(o => ['replace', extend(o)])
|
|
157
|
+
/**
|
|
158
|
+
* @type {(extend: (o: Branch3<T>) => Branch7<T>) =>
|
|
159
|
+
* (replace: (r: Node<T>) => Branch5<T>) =>
|
|
160
|
+
* (result: Result<T>) =>
|
|
161
|
+
* Result<T>}
|
|
162
|
+
*/
|
|
163
|
+
const merge3 = extend => merge(o => ['overflow', split(extend(o))])
|
|
165
164
|
return init => {
|
|
166
|
-
/** @typedef {typeof cmp extends Cmp<infer T> ? T : never} T*/
|
|
167
165
|
/** @type {(node: Node<T>) => Result<T>} */
|
|
168
166
|
const f = node => {
|
|
169
167
|
switch (node.length) {
|
|
@@ -188,14 +186,14 @@ const visit = ({ found, notFound }) => cmp => {
|
|
|
188
186
|
switch (i3(v1)) {
|
|
189
187
|
case 0: {
|
|
190
188
|
return merge2
|
|
191
|
-
(
|
|
189
|
+
(e => [...e, v1, n2])
|
|
192
190
|
(r => [r, v1, n2])
|
|
193
191
|
(f(n0))
|
|
194
192
|
}
|
|
195
193
|
case 1: { return found.branch3(init)(node) }
|
|
196
194
|
default: {
|
|
197
195
|
return merge2
|
|
198
|
-
(
|
|
196
|
+
(e => [n0, v1, ...e])
|
|
199
197
|
(r => [n0, v1, r])
|
|
200
198
|
(f(n2))
|
|
201
199
|
}
|
|
@@ -305,7 +303,7 @@ const replaceVisitor = {
|
|
|
305
303
|
notFound: notFoundGet,
|
|
306
304
|
}
|
|
307
305
|
|
|
308
|
-
/** @type {<T>(node: Node<T>) => seq.
|
|
306
|
+
/** @type {<T>(node: Node<T>) => seq.List<T>} */
|
|
309
307
|
const values = node => () => {
|
|
310
308
|
const f = () => {
|
|
311
309
|
switch (node.length) {
|
|
@@ -339,7 +337,7 @@ module.exports = {
|
|
|
339
337
|
* @type { <T>(cmp: Cmp<T>) => (node: Node<T>) => T|undefined }
|
|
340
338
|
*/
|
|
341
339
|
getVisitor: cmp => node => {
|
|
342
|
-
const result = visit(getVisitor)(cmp)(() => { throw '' })(node)
|
|
340
|
+
const result = visit(getVisitor)(cmp)(() => { throw 'getVisitor' })(node)
|
|
343
341
|
if (result[0] === 'done') { return result[1] }
|
|
344
342
|
return undefined
|
|
345
343
|
},
|
package/types/btree/test.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const btree = require('.')
|
|
2
2
|
const { setVisitor, values } = btree
|
|
3
3
|
const { cmp } = require('../function/compare')
|
|
4
|
-
const list = require('../
|
|
4
|
+
const list = require('../list')
|
|
5
5
|
|
|
6
6
|
/** @type {(node: btree.Node<string>) => (value: string) => btree.Node<string>} */
|
|
7
7
|
const set = node => value => {
|
|
@@ -22,7 +22,7 @@ const test = () => {
|
|
|
22
22
|
_map = set(_map)('f')
|
|
23
23
|
//
|
|
24
24
|
{
|
|
25
|
-
/** @type {
|
|
25
|
+
/** @type {list.Result<string>} */
|
|
26
26
|
let _item = list.next(values(_map))
|
|
27
27
|
while (_item !== undefined) {
|
|
28
28
|
_item = list.next(_item.tail)
|
|
@@ -2,44 +2,76 @@
|
|
|
2
2
|
* @template A
|
|
3
3
|
* @template B
|
|
4
4
|
* @template R
|
|
5
|
-
* @typedef {(a: A) => (b: B) => R}
|
|
5
|
+
* @typedef {(a: A) => (b: B) => R} Binary
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* @template
|
|
10
|
-
* @
|
|
11
|
-
* @typedef {BinaryOperator<R, T, R>} ReduceOperator
|
|
9
|
+
* @template I,O
|
|
10
|
+
* @typedef {Binary<O, I, O>} Reduce
|
|
12
11
|
*/
|
|
13
12
|
|
|
14
|
-
/** @type {(separator: string) =>
|
|
13
|
+
/** @type {(separator: string) => Fold<string>} */
|
|
15
14
|
const join = separator => prior => value => `${prior}${separator}${value}`
|
|
16
15
|
|
|
17
|
-
/** @type {
|
|
16
|
+
/** @type {Fold<number>} */
|
|
18
17
|
const addition = a => b => a + b
|
|
19
18
|
|
|
20
19
|
/**
|
|
21
20
|
* @template T
|
|
22
21
|
* @template R
|
|
23
|
-
* @typedef {(value: T) => R}
|
|
22
|
+
* @typedef {(value: T) => R} Unary
|
|
24
23
|
*/
|
|
25
24
|
|
|
26
|
-
/** @type {
|
|
25
|
+
/** @type {Unary<boolean, boolean>} */
|
|
27
26
|
const logicalNot = v => !v
|
|
28
27
|
|
|
29
28
|
/**
|
|
30
29
|
* @template T
|
|
31
|
-
* @typedef {
|
|
30
|
+
* @typedef {Binary<T, T, boolean>} Equal
|
|
32
31
|
*/
|
|
33
32
|
|
|
34
33
|
/** @type {<T>(a: T) => (b: T) => boolean} */
|
|
35
34
|
const strictEqual = a => b => a === b
|
|
36
35
|
|
|
37
|
-
/** @type {
|
|
36
|
+
/** @type {Fold<number>} */
|
|
38
37
|
const min = a => b => a < b ? a : b
|
|
39
38
|
|
|
40
|
-
/** @type {
|
|
39
|
+
/** @type {Fold<number>} */
|
|
41
40
|
const max = a => b => a > b ? a : b
|
|
42
41
|
|
|
42
|
+
/**
|
|
43
|
+
* @template I,O
|
|
44
|
+
* @typedef {(input: I) => readonly[O, Scan<I,O>]} Scan
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @template I,S,O
|
|
49
|
+
* @typedef {(prior: S) => (input: I) => readonly[O, S]} StateScan
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
/** @type {<I, S, O>(op: StateScan<I, S, O>) => (prior: S) => Scan<I, O>} */
|
|
53
|
+
const stateScanToScan = op => prior => i => {
|
|
54
|
+
const [o, s] = op(prior)(i)
|
|
55
|
+
return [o, stateScanToScan(op)(s)]
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** @type {<I, O>(reduce: Reduce<I, O>) => (prior: O) => Scan<I, O>} */
|
|
59
|
+
const reduceToScan = reduce => prior => i => {
|
|
60
|
+
const result = reduce(prior)(i)
|
|
61
|
+
return [result, reduceToScan(reduce)(result)]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @template T
|
|
66
|
+
* @typedef {Reduce<T, T>} Fold
|
|
67
|
+
*/
|
|
68
|
+
|
|
69
|
+
/** @type {<T>(fold: Fold<T>) => Scan<T, T>} */
|
|
70
|
+
const foldToScan = op => init => [init, reduceToScan(op)(init)]
|
|
71
|
+
|
|
72
|
+
/** @type {(a: number) => () => number} */
|
|
73
|
+
const counter = a => () => a + 1
|
|
74
|
+
|
|
43
75
|
module.exports = {
|
|
44
76
|
/** @readonly */
|
|
45
77
|
join,
|
|
@@ -53,4 +85,12 @@ module.exports = {
|
|
|
53
85
|
min,
|
|
54
86
|
/** @readonly */
|
|
55
87
|
max,
|
|
88
|
+
/** @readonly */
|
|
89
|
+
stateScanToScan,
|
|
90
|
+
/** @readonly */
|
|
91
|
+
reduceToScan,
|
|
92
|
+
/** @readonly */
|
|
93
|
+
foldToScan,
|
|
94
|
+
/** @readonly */
|
|
95
|
+
counter,
|
|
56
96
|
}
|