functionalscript 0.0.237 → 0.0.241

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.
@@ -5,9 +5,7 @@ name: Node.js CI
5
5
 
6
6
  on:
7
7
  push:
8
- branches: [ main ]
9
8
  pull_request:
10
- branches: [ main ]
11
9
 
12
10
  jobs:
13
11
  build:
@@ -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
+ ```
@@ -0,0 +1,35 @@
1
+ const object = require('../../types/object')
2
+
3
+ /**
4
+ * @template M
5
+ * @typedef {{
6
+ * readonly at: (moduleId: string) => (moduleMap: M) => ModuleState | undefined
7
+ * readonly insert: (moduleId: string) => (moduleState: ModuleState) => (moduleMap: M) => M
8
+ * }} ModuleMapInterface
9
+ */
10
+
11
+ /**
12
+ * @typedef {|
13
+ * readonly['ok', Module] |
14
+ * readonly['error', ModuleError] |
15
+ * readonly['building']
16
+ * } ModuleState
17
+ */
18
+
19
+ /**
20
+ * @typedef {{
21
+ * readonly exports: unknown
22
+ * readonly requireMap: object.Map<string>
23
+ * }} Module
24
+ */
25
+
26
+ /**
27
+ * @typedef {|
28
+ * 'file not found' |
29
+ * 'compile error' |
30
+ * 'runtime error' |
31
+ * 'circular reference'
32
+ * } ModuleError
33
+ */
34
+
35
+ module.exports = {}
@@ -1,9 +1,5 @@
1
- const { todo } = require('../../../dev')
2
1
  const json = require('../../../json')
3
- const { isObject } = json
4
2
  const seq = require('../../../types/sequence')
5
- const path = require('../../path')
6
- const { at } = require('../../../types/object')
7
3
 
8
4
  /** @typedef {readonly[string, string]} DependencyJson */
9
5
 
@@ -21,41 +17,7 @@ const isDependenciesJson = j => {
21
17
  return seq.every(seq.map(isDependencyJson)(Object.entries(j)))
22
18
  }
23
19
 
24
- /** @typedef {readonly[string, seq.Sequence<string>]} IdPath */
25
-
26
- /** @type {(prior: readonly[string|undefined, seq.Sequence<string>]) => seq.Thunk<IdPath>} */
27
- const variants = prior => () => {
28
- const [a, b] = prior
29
- const r = seq.next(b)
30
- if (r === undefined) { return undefined }
31
- const { first, tail } = r
32
- /** @type {IdPath} */
33
- const n = [a === undefined ? first : `${a}/${first}`, tail]
34
- return { first: n, tail: variants(n) }
35
- }
36
-
37
- /** @type {(d: DependencyMapJson) => (p: IdPath) => IdPath|undefined} */
38
- const mapDependency = d => ([external, internal]) => {
39
- const id = at(external)(d)
40
- if (id === undefined) { return undefined }
41
- return [id, internal]
42
- }
43
-
44
- /** @typedef {readonly[string, string]} GlobalPath */
45
-
46
- /** @type {(d: DependenciesJson) => (p: path.Items) => GlobalPath|undefined} */
47
- const idPath = d => p => {
48
- if (d === undefined) { return undefined }
49
- const v = variants([undefined, p])
50
- const valid = seq.first(undefined)(seq.filterMap(mapDependency(d))(v))
51
- if (valid === undefined) { return undefined }
52
- const [packId, localId] = valid
53
- return [packId, seq.join('/')(localId)]
54
- }
55
-
56
20
  module.exports = {
57
21
  /** @readonly */
58
22
  isDependenciesJson,
59
- /** @readonly */
60
- idPath,
61
23
  }
@@ -10,28 +10,3 @@ const seq = require('../../../types/sequence')
10
10
  if (!_.isDependenciesJson({'a':'b'})) { throw 'error' }
11
11
  if (_.isDependenciesJson({ 'a': 12 })) { throw 'error' }
12
12
  }
13
-
14
- /** @type {(g: _.GlobalPath|undefined) => string} */
15
- const stringify = g => {
16
- if (g === undefined) { throw g }
17
- return json.stringify(sort)(g)
18
- }
19
-
20
- {
21
- if (_.idPath(undefined)(['a', 'b']) !== undefined) { throw 'error' }
22
- if (_.idPath({})(['b']) !== undefined) { throw 'error' }
23
- if (_.idPath({b:'x'})(['d']) !== undefined) { throw 'error'}
24
- {
25
- const result = stringify(_.idPath({ b: 'x' })(['b']))
26
- if (result !== '["x",""]') { throw result }
27
- }
28
- if (_.idPath({ 'b/r': 'x' })(['b']) !== undefined) { throw 'error'}
29
- {
30
- const result = stringify(_.idPath({ 'b/r': 'x' })(['b', 'r']))
31
- if (result !== '["x",""]') { throw result }
32
- }
33
- {
34
- const result = stringify(_.idPath({ 'b/r': 'x' })(['b', 'r', 'd', 't']))
35
- if (result !== '["x","d/t"]') { throw result }
36
- }
37
- }
@@ -1,8 +1,11 @@
1
1
  const json = require('../../json')
2
2
  const dep = require('./dependencies')
3
+ const object = require('../../types/object')
4
+ const run = require('../run')
3
5
 
4
6
  /**
5
7
  * @typedef {{
8
+ * readonly name: string
6
9
  * readonly version: string
7
10
  * readonly dependencies?: dep.DependenciesJson
8
11
  * }} PackageJson
@@ -11,6 +14,7 @@ const dep = require('./dependencies')
11
14
  /** @type {(j: json.Unknown) => j is PackageJson} */
12
15
  const isPackageJson = j => {
13
16
  if (!json.isObject(j)) { return false }
17
+ if (typeof j.name !== 'string') { return false }
14
18
  if (typeof j.version !== 'string') { return false }
15
19
  if (!dep.isDependenciesJson(j.dependencies)) { return false }
16
20
  return true
@@ -18,10 +22,13 @@ const isPackageJson = j => {
18
22
 
19
23
  /**
20
24
  * @typedef {{
21
- * readonly dependencies: dep.DependenciesJson
25
+ * readonly dependency: (localPackageId: string) => string | undefined
26
+ * readonly file: (localFileId: string) => string | undefined
22
27
  * }} Package
23
28
  */
24
29
 
30
+ /** @typedef {(packageId: string) => Package | undefined} PackageGet */
31
+
25
32
  module.exports = {
26
33
  /** @readonly */
27
34
  isPackageJson,
@@ -5,12 +5,12 @@ require('./dependencies/test')
5
5
  {
6
6
  if (_.isPackageJson(null)) { throw 'error' }
7
7
  if (_.isPackageJson({})) { throw 'error' }
8
- if (_.isPackageJson({version:12})) { throw 'error' }
9
- if (!_.isPackageJson({version:"12"})) { throw 'error' }
8
+ if (_.isPackageJson({name:'x',version:12})) { throw 'error' }
9
+ if (!_.isPackageJson({name:'x',version:"12"})) { throw 'error' }
10
10
  if (_.isPackageJson({version:"",dependencies:[]})) { throw 'error' }
11
- if (!_.isPackageJson({ version: "", dependencies: {} })) { throw 'error' }
12
- if (_.isPackageJson({ version: "", dependencies: { x: 12} })) { throw 'error' }
13
- if (!_.isPackageJson({ version: "", dependencies: { x: "12" } })) { throw 'error' }
11
+ if (!_.isPackageJson({name:'a', version: "", dependencies: {} })) { throw 'error' }
12
+ if (_.isPackageJson({name:'b', version: "", dependencies: { x: 12} })) { throw 'error' }
13
+ if (!_.isPackageJson({name:'c', version: "", dependencies: { x: "12" } })) { throw 'error' }
14
14
  }
15
15
 
16
16
  module.exports = {}
@@ -1,6 +1,9 @@
1
1
  const seq = require("../../types/sequence")
2
2
  const option = require("../../types/option")
3
3
  const { compose } = require("../../types/function")
4
+ const dep = require("../package/dependencies")
5
+ const { at } = require("../../types/object")
6
+ const pack = require("../package")
4
7
 
5
8
  /** @typedef {readonly string[]} Items */
6
9
 
@@ -9,7 +12,7 @@ const { compose } = require("../../types/function")
9
12
  * readonly external: boolean
10
13
  * readonly dir: boolean
11
14
  * readonly items: Items
12
- * }} Path
15
+ * }} LocalPath
13
16
  */
14
17
 
15
18
  /** @type {(path: string) => readonly string[]} */
@@ -34,8 +37,8 @@ const normItemsOp = prior => item => {
34
37
  /** @type {(items: seq.Sequence<string>) => seq.Sequence<string>|undefined} */
35
38
  const normItems = compose(seq.reduce(normItemsOp)([]))(option.map(seq.reverse))
36
39
 
37
- /** @type {(local: string) => (path: string) => Path|undefined} */
38
- const parse = local => {
40
+ /** @type {(local: string) => (path: string) => LocalPath|undefined} */
41
+ const parseLocal = local => {
39
42
  /** @type {(path: string) => readonly[boolean, seq.Sequence<string>]} */
40
43
  const fSeq = path => {
41
44
  const pathSeq = split(path)
@@ -44,7 +47,7 @@ const parse = local => {
44
47
  default: { return [true, pathSeq] }
45
48
  }
46
49
  }
47
- /** @type {(path: string) => Path|undefined} */
50
+ /** @type {(path: string) => LocalPath|undefined} */
48
51
  const f = path => {
49
52
  const [external, items] = fSeq(path)
50
53
  const n = normItems(items)
@@ -58,9 +61,56 @@ const parse = local => {
58
61
  return f
59
62
  }
60
63
 
64
+ /** @typedef {readonly[string, seq.Sequence<string>]} IdPath */
65
+
66
+ /** @type {(prior: readonly[string|undefined, seq.Sequence<string>]) => seq.Thunk<IdPath>} */
67
+ const variants = prior => () => {
68
+ const [a, b] = prior
69
+ const r = seq.next(b)
70
+ if (r === undefined) { return undefined }
71
+ const { first, tail } = r
72
+ /** @type {IdPath} */
73
+ const n = [a === undefined ? first : `${a}/${first}`, tail]
74
+ return { first: n, tail: variants(n) }
75
+ }
76
+
77
+ /** @type {(d: dep.DependencyMapJson) => (p: IdPath) => IdPath|undefined} */
78
+ const mapDependency = d => ([external, internal]) => {
79
+ const id = at(external)(d)
80
+ return id === undefined ? undefined : [id, internal]
81
+ }
82
+
83
+ /**
84
+ * @typedef {{
85
+ * readonly name: string,
86
+ * readonly items: Items,
87
+ * readonly dir: boolean,
88
+ * }} Path
89
+ */
90
+
91
+ /** @type {(d: dep.DependenciesJson) => (dir: boolean) => (items: seq.Sequence<string>) => Path|undefined} */
92
+ const parseGlobal = d => dir => items => {
93
+ if (d === undefined) { return undefined }
94
+ const v = variants([undefined, items])
95
+ const r = seq.first(undefined)(seq.filterMap(mapDependency(d))(v))
96
+ if (r === undefined) { return undefined }
97
+ return { name: r[0], items: seq.toArray(r[1]), dir }
98
+ }
99
+
100
+ /** @type {(name: string) => (dependencies: dep.DependenciesJson) => (local: string) => (path: string) => Path|undefined } */
101
+ const parse = name => dependencies => local => path => {
102
+ const parsed = parseLocal(local)(path)
103
+ if (parsed === undefined) { return undefined }
104
+ const {external, dir, items} = parsed
105
+ if (!external) { return { name, items, dir } }
106
+ return parseGlobal(dependencies)(dir)(items)
107
+ }
108
+
61
109
  module.exports = {
62
110
  /** @readonly */
63
- split,
111
+ parseLocal,
112
+ /** @readonly */
113
+ parseGlobal,
64
114
  /** @readonly */
65
115
  parse,
66
116
  }
@@ -1,47 +1,64 @@
1
1
  const _ = require('.')
2
2
  const json = require('../../json')
3
- const { identity, compose } = require('../../types/function')
4
- const seq = require('../../types/sequence')
3
+ const { identity } = require('../../types/function')
5
4
 
6
- const stringify = json.stringify(identity)
5
+ /** @type {(g: json.Unknown|undefined) => string} */
6
+ const stringify = g => {
7
+ if (g === undefined) { throw g }
8
+ return json.stringify(identity)(g)
9
+ }
7
10
 
8
11
  {
9
- const result = _.parse('')('./a')
10
- if (result === undefined) { throw result }
12
+ const p = { name: '', version: '' }
13
+ const result = _.parseLocal('')('./a')
11
14
  if (stringify(result) !== '{"external":false,"dir":false,"items":["a"]}') { throw result }
12
15
  }
13
16
 
14
17
  {
15
- const result = _.parse('')('./a/')
16
- if (result === undefined) { throw result }
18
+ const result = _.parseLocal('')('./a/')
17
19
  if (stringify(result) !== '{"external":false,"dir":true,"items":["a"]}') { throw result }
18
20
  }
19
21
 
20
22
  {
21
- const result = _.parse('')('..')
23
+ const result = _.parseLocal('')('..')
22
24
  if (result !== undefined) { throw result }
23
25
  }
24
26
 
25
27
  {
26
- const result = _.parse('a')('')
27
- if (result === undefined) { throw result }
28
+ const result = _.parseLocal('a')('')
28
29
  if (stringify(result) !== '{"external":true,"dir":false,"items":[]}') { throw result }
29
30
  }
30
31
 
31
32
  {
32
- const result = _.parse('')('./a/b/.././c')
33
- if (result === undefined) { throw result }
33
+ const result = _.parseLocal('')('./a/b/.././c')
34
34
  if (stringify(result) !== '{"external":false,"dir":false,"items":["a","c"]}') { throw result }
35
35
  }
36
36
 
37
37
  {
38
- const result = _.parse('x/r')('./a/b/.././c')
39
- if (result === undefined) { throw result }
38
+ const result = _.parseLocal('x/r')('./a/b/.././c')
40
39
  if (stringify(result) !== '{"external":false,"dir":false,"items":["x","r","a","c"]}') { throw result }
41
40
  }
42
41
 
43
42
  {
44
- const result = _.parse('a')('a/b/.././c')
45
- if (result === undefined) { throw result }
43
+ const result = _.parseLocal('a')('a/b/.././c')
46
44
  if (stringify(result) !== '{"external":true,"dir":false,"items":["a","c"]}') { throw result }
47
45
  }
46
+
47
+ {
48
+ if (_.parseGlobal(undefined)(false)(['a', 'b']) !== undefined) { throw 'error' }
49
+ if (_.parseGlobal({})(false)(['b']) !== undefined) { throw 'error' }
50
+ if (_.parseGlobal({ b: 'x' })(false)(['d']) !== undefined) { throw 'error' }
51
+ {
52
+ const result = stringify(_.parseGlobal({ b: 'x' })(false)(['b']))
53
+ if (result !== '["x",""]') { throw result }
54
+ }
55
+ if (_.parseGlobal({ 'b/r': 'x' })(false)(['b']) !== undefined) { throw 'error' }
56
+ {
57
+ const result = stringify(_.parseGlobal({ 'b/r': 'x' })(false)(['b', 'r']))
58
+ if (result !== '["x",""]') { throw result }
59
+ }
60
+ {
61
+ const result = stringify(_.parseGlobal({ 'b/r': 'x' })(false)(['b', 'r', 'd', 't']))
62
+ if (result !== '["x","d/t"]') { throw result }
63
+ }
64
+ }
@@ -9,7 +9,7 @@ const result = require('../../types/result')
9
9
 
10
10
  /**
11
11
  * @template T
12
- * @typedef {(prior: T) => (path: string) => ModuleResult<T>} Require
12
+ * @typedef {(path: string) => (prior: T) => ModuleResult<T>} Require
13
13
  */
14
14
 
15
15
  /** @typedef {(source: string) => result.Result<Module, unknown>} Compile */
@@ -3,11 +3,11 @@ const { unwrap } = require('../../types/result')
3
3
  const run = require('../../commonjs/run')
4
4
 
5
5
  /** @type {(f: Function) => run.Module} */
6
- const createModule = f => req => mutableInfo => {
6
+ const build = f => immutableRequire => mutableData => {
7
7
  /** @type {(path: string) => unknown} */
8
8
  const mutableRequire = path => {
9
- const [result, info] = req(mutableInfo)(path)
10
- mutableInfo = info
9
+ const [result, data] = immutableRequire(path)(mutableData)
10
+ mutableData = data
11
11
  return unwrap(result)
12
12
  }
13
13
  const result = tryCatch(() => {
@@ -15,12 +15,12 @@ const createModule = f => req => mutableInfo => {
15
15
  f(mutableModule, mutableRequire)
16
16
  return mutableModule.exports
17
17
  })
18
- return [result, mutableInfo]
18
+ return [result, mutableData]
19
19
  }
20
20
 
21
21
  /** @type {run.Compile} */
22
22
  const compile = source =>
23
- tryCatch(() => createModule(Function('module', 'require', `"use strict";${source}`)))
23
+ tryCatch(() => build(Function('module', 'require', `"use strict";${source}`)))
24
24
 
25
25
  module.exports = {
26
26
  /** @readonly */
@@ -41,7 +41,7 @@ const run = require('../../commonjs/run')
41
41
  if (d[0] !== 'ok') { throw d }
42
42
 
43
43
  /** @type {run.Require<number>} */
44
- const req = prior => path => {
44
+ const req = path => prior => {
45
45
  if (path !== 'm') { throw path }
46
46
  return d[1](req)(prior + 1)
47
47
  }
@@ -1,7 +1,6 @@
1
1
  const cp = require('child_process')
2
2
  const fs = require('fs')
3
- const json = require('../../../json')
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.237",
3
+ "version": "0.0.241",
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.11",
29
+ "@types/node": "^16.11.12",
23
30
  "typescript": "^4.5.2"
24
31
  }
25
32
  }
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
- // "resolveJsonModule": true, /* Enable importing .json files */
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 */
@@ -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>(overflow: (o: Branch3<T>) => Result<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 = overflow => replace => result => {
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 overflow(result[1]) }
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
- (o => [...o, v1, n2])
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
- (o => [n0, v1, ...o])
196
+ (e => [n0, v1, ...e])
199
197
  (r => [n0, v1, r])
200
198
  (f(n2))
201
199
  }
@@ -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
  },
@@ -1,86 +1,80 @@
1
1
  const option = require("../option")
2
+ const btree = require('../btree')
2
3
  const { getVisitor, setVisitor, values } = require("../btree")
4
+ const compare = require("../function/compare")
3
5
  const { cmp } = require("../function/compare")
4
6
  const seq = require("../sequence")
5
7
 
6
- /** @typedef {import("../function/compare").Sign} Sign */
8
+ /** @typedef {compare.Sign} Sign */
7
9
 
8
10
  /**
9
11
  * @template T
10
- * @typedef {import("../btree").Leaf1<T>} Leaf1
12
+ * @typedef {btree.Leaf1<T>} Leaf1
11
13
  */
12
14
 
13
15
  /**
14
16
  * @template T
15
- * @typedef {import("../btree").Node<T>} TNode
17
+ * @typedef {btree.Node<T>} TNode
16
18
  */
17
19
 
18
20
  /**
19
21
  * @template T
20
- * @typedef {import("../function/compare").Compare<T>} Cmp
22
+ * @typedef {compare.Compare<T>} Cmp
21
23
  */
22
24
 
23
25
  /**
24
26
  * @template T
25
- * @typedef {readonly [string, T]} Entry
27
+ * @typedef {readonly[string, T]} Entry
26
28
  */
27
29
 
28
- /**
30
+ /**
29
31
  * @template T
30
- * @typedef {{
31
- * readonly get: (name: string) => T|undefined
32
- * readonly set: (name: string) => (value: T) => Map<T>
33
- * readonly entries: seq.Sequence<Entry<T>>
34
- * readonly root: undefined|TNode<Entry<T>>
35
- * }} Map
32
+ * @typedef {undefined|TNode<Entry<T>>} Map
36
33
  */
37
34
 
38
35
  /** @type {(a: string) => <T>(b: Entry<T>) => Sign} */
39
36
  const keyCmp = a => ([b]) => cmp(a)(b)
40
37
 
41
- /** @type {<T>(node: TNode<Entry<T>>) => Map<T>} */
42
- const create = root => ({
43
- get: name => option.map(([,value]) => value)(getVisitor(keyCmp(name))(root)),
44
- set: name => value => {
45
- const result = setVisitor(keyCmp(name))(() => [name, value])(root)
46
- switch (result[0]) {
47
- case 'replace': case 'overflow': { return create(result[1]) }
48
- default: { throw '' }
49
- }
50
- },
51
- entries: values(root),
52
- root,
53
- })
38
+ /** @type {(name: string) => <T>(map: Map<T>) => T|undefined} */
39
+ const at = name => map => {
40
+ if (map === undefined) { return undefined }
41
+ const result = getVisitor(keyCmp(name))(map)
42
+ return result === undefined ? undefined : result[1]
43
+ }
54
44
 
55
- /**
56
- * @type {{
57
- * readonly get: (name: string) => undefined
58
- * readonly set: (name: string) => <T>(value: T) => Map<T>
59
- * readonly entries: []
60
- * readonly root: undefined
61
- * }}
62
- */
63
- const empty = {
64
- get: () => undefined,
65
- set: name => value => create([[name, value]]),
66
- entries: [],
67
- root: undefined
45
+ /** @type {(name: string) => <T>(value: T) => (map: Map<T>) => Map<T>} */
46
+ const set = name => value => map => {
47
+ /** @type {Entry<typeof value>} */
48
+ const entry = [name, value]
49
+ if (map === undefined) { return [entry] }
50
+ const result = setVisitor(keyCmp(name))(() => entry)(map)
51
+ switch (result[0]) {
52
+ case 'replace': case 'overflow': { return result[1] }
53
+ default: { throw 'invalid BTree operation' }
54
+ }
68
55
  }
69
56
 
57
+ /** @type {<T>(map: Map<T>) => seq.Sequence<Entry<T>>} */
58
+ const entries = map => map === undefined ? [] : values(map)
59
+
70
60
  /** @type {<T>(map: Map<T>) => (entry: Entry<T>) => Map<T>} */
71
- const setOperator = map => ([k, v]) => map.set(k)(v)
61
+ const setOp = map => ([name, value]) => set(name)(value)(map)
72
62
 
73
63
  /** @type {<T>(entries: seq.Sequence<Entry<T>>) => Map<T>} */
74
64
  const fromEntries = entries => {
75
- /** @typedef {typeof entries extends seq.Sequence<Entry<infer T>> ? T : never} T */
76
- /** @type {Map<T>} */
77
- const init = empty
78
- return seq.reduce(setOperator)(init)(entries)
65
+ /** @typedef {typeof entries extends seq.Sequence<Entry<infer T>> ? T : never} T */
66
+ return seq.reduce(setOp)(/** @type {Map<T>} */(undefined))(entries)
79
67
  }
80
68
 
81
69
  module.exports = {
82
70
  /** @readonly */
83
- empty,
71
+ empty: undefined,
72
+ /** @readonly */
73
+ at,
74
+ /** @readonly */
75
+ set,
76
+ /** @readonly */
77
+ entries,
84
78
  /** @readonly */
85
79
  fromEntries,
86
80
  }
package/types/map/test.js CHANGED
@@ -1,59 +1,60 @@
1
- const { empty } = require('.')
2
- const list = require('../sequence')
1
+ const { at, set, empty, entries } = require('.')
2
+ const seq = require('../sequence')
3
3
 
4
4
  {
5
- let m = empty.set('a')(1)
5
+ let m = set('a')(1)(undefined)
6
6
 
7
- if (m.get('a') !== 1) { throw 'error' }
8
- if (m.get('b') !== undefined) { throw 'error' }
7
+ if (at('a')(m) !== 1) { throw 'error' }
8
+ if (at('b')(m) !== undefined) { throw 'error' }
9
9
 
10
- m = m.set('b')(2)
10
+ m = set('b')(2)(m)
11
11
 
12
- if (m.get('a') !== 1) { throw 'error' }
13
- if (m.get('b') !== 2) { throw 'error' }
14
- if (m.get('c') !== undefined) { throw 'error' }
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 = m.set('z')(3)
16
+ m = set('z')(3)(m)
17
17
 
18
- if (m.get('a') !== 1) { throw 'error' }
19
- if (m.get('b') !== 2) { throw 'error' }
20
- if (m.get('z') !== 3) { throw 'error' }
21
- if (m.get('') !== undefined) { throw 'error' }
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 = m.set('')(4)
23
+ m = set('')(4)(m)
24
24
 
25
- if (m.get('a') !== 1) { throw 'error' }
26
- if (m.get('b') !== 2) { throw 'error' }
27
- if (m.get('z') !== 3) { throw 'error' }
28
- if (m.get('') !== 4) { throw 'error' }
29
- if (m.get('Hello world!') !== undefined) { throw 'error' }
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 = m.set('Hello world!')(42)
31
+ m = set('Hello world!')(42)(m)
32
32
 
33
- if (m.get('a') !== 1) { throw 'error' }
34
- if (m.get('b') !== 2) { throw 'error' }
35
- if (m.get('z') !== 3) { throw 'error' }
36
- if (m.get('') !== 4) { throw 'error' }
37
- if (m.get('Hello world!') !== 42) { throw 'error' }
38
- if (m.get('x') !== undefined) { throw 'error' }
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
- const m = empty.set('x')(12).set('y')(44)
45
- if (m.get('x') !== 12) { throw 'error' }
46
- if (m.get('y') !== 44) { throw 'error' }
47
- if (m.get('a') !== undefined) { throw 'error' }
48
- const entries = Array.from(list.iterable(m.entries))
49
- if (entries.length !== 2) { throw 'error' }
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 = m.set((i*i).toString())(i)
57
+ m = set((i * i).toString())(i)(m)
57
58
  /*
58
59
  console.log()
59
60
  console.log(`# ${i}`)
@@ -1,5 +1,6 @@
1
1
  const seq = require('../sequence')
2
2
  const map = require('../map')
3
+ const { compose } = require('../function')
3
4
 
4
5
  /**
5
6
  * @template T
@@ -17,7 +18,7 @@ const map = require('../map')
17
18
  const at = name => object => Object.getOwnPropertyDescriptor(object, name)?.value
18
19
 
19
20
  /** @type {<T>(entries: seq.Sequence<Entry<T>>) => seq.Sequence<Entry<T>>} */
20
- const sort = entries => map.fromEntries(entries).entries
21
+ const sort = entries => map.entries(map.fromEntries(entries))
21
22
 
22
23
  module.exports = {
23
24
  /** @readonly */