functionalscript 0.0.156 → 0.0.163

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/array/index.js CHANGED
@@ -1,3 +1,10 @@
1
+ const option = require('../option')
2
+
3
+ /**
4
+ * @template T
5
+ * @typedef {readonly T[]} Array
6
+ */
7
+
1
8
  /**
2
9
  * @template T
3
10
  * @typedef {readonly [T]} Array1
@@ -33,4 +40,51 @@
33
40
 
34
41
  /** @typedef {0|1|2|3|4} Index5 */
35
42
 
36
- module.exports = {}
43
+ /** @type {<T>(_: Array<T>) => Array<T>} */
44
+ const uncheckTail = a => a.slice(1)
45
+
46
+ /** @type {<T>(_: Array<T>) => Array<T>} */
47
+ const uncheckHead = a => a.slice(0, -1)
48
+
49
+ /** @type {<T>(_: Array<T>) => T|undefined} */
50
+ const first = a => a[0]
51
+
52
+ /** @type {<T>(_: Array<T>) => T|undefined} */
53
+ const last = a => a[a.length - 1]
54
+
55
+ /** @type {<T>(_: Array<T>) => Array<T>|undefined} */
56
+ const tail = a => a.length === 0 ? undefined : uncheckTail(a)
57
+
58
+ /** @type {<T>(_: Array<T>) => readonly [T, Array<T>]|undefined} */
59
+ const splitFirst = a => {
60
+ /** @typedef {typeof a[0]} T*/
61
+ /** @type {(_: T) => readonly [T, Array<T>]} */
62
+ const split = first => [first, uncheckTail(a)]
63
+ return option.map(split)(a[0])
64
+ }
65
+
66
+ /** @type {<T>(_: Array<T>) => Array<T>|undefined} */
67
+ const head = a => a.length === 0 ? undefined : uncheckHead(a)
68
+
69
+ /** @type {<T>(_: Array<T>) => readonly [Array<T>, T]|undefined} */
70
+ const splitLast = a => {
71
+ /** @typedef {typeof a[0]} T*/
72
+ /** @type {(_: T) => readonly [Array<T>, T]} */
73
+ const split = x => [uncheckHead(a), x]
74
+ return option.map(split)(last(a))
75
+ }
76
+
77
+ module.exports = {
78
+ /** @readnly */
79
+ first,
80
+ /** @readonly */
81
+ last,
82
+ /** @readonly */
83
+ head,
84
+ /** @readonly */
85
+ tail,
86
+ /** @readonly */
87
+ splitFirst,
88
+ /** @readonly */
89
+ splitLast,
90
+ }
@@ -1,6 +1,13 @@
1
- const { pipe } = require('../lib')
1
+ const { todo } = require('../../dev')
2
+ const { pipe } = require('../../func')
3
+ const mapReduce = require('../../map-reduce')
2
4
 
3
- /** @type {<T, R>(f: (value: T) => Promise<R>) => (c: AsyncIterable<T>) => AsyncIterable<R>} */
5
+ /**
6
+ * @template T
7
+ * @typedef {Promise<T>|T} PromiseOrValue
8
+ */
9
+
10
+ /** @type {<T, R>(f: (value: T) => PromiseOrValue<R>) => (c: AsyncIterable<T>) => AsyncIterable<R>} */
4
11
  const map = f => c => ({
5
12
  async *[Symbol.asyncIterator]() {
6
13
  for await (const i of c) {
@@ -30,24 +37,24 @@ const filter = f => c => ({
30
37
  })
31
38
 
32
39
  /** @type {<T, R>(f: (value: T) => AsyncIterable<R>) => (c: AsyncIterable<T>) => AsyncIterable<R>} */
33
- const flatMap = f => pipe(map(async x => f(x)))(flatten)
40
+ const flatMap = f => pipe(map(f))(flatten)
34
41
 
35
42
  /**
36
43
  * @template A
37
44
  * @template T
38
- * @typedef {(accumulator: A) => (value: T) => Promise<A>} ReduceFn
45
+ * @typedef {(accumulator: A) => (value: T) => PromiseOrValue<A>} Merge
39
46
  */
40
47
 
41
- /** @type {<A, T>(f: ReduceFn<A, T>) => (init: A) => (c: AsyncIterable<T>) => Promise<A>} */
42
- const reduce = reduceFn => init => async c => {
48
+ /** @type {<A, T>(f: Merge<A, T>) => (init: A) => (c: AsyncIterable<T>) => Promise<A>} */
49
+ const reduce = merge => init => async c => {
43
50
  let result = init
44
51
  for await (const i of c) {
45
- result = await reduceFn(result)(i)
52
+ result = await merge(result)(i)
46
53
  }
47
54
  return result
48
55
  }
49
56
 
50
- /** @type {<A, T>(f: ReduceFn<A, T>) => (init: A) => (c: AsyncIterable<T>) => AsyncIterable<A>} */
57
+ /** @type {<A, T>(f: Merge<A, T>) => (init: A) => (c: AsyncIterable<T>) => AsyncIterable<A>} */
51
58
  const exclusiveScan = reduceFn => init => c => ({
52
59
  async *[Symbol.asyncIterator]() {
53
60
  let result = init
@@ -58,7 +65,7 @@ const exclusiveScan = reduceFn => init => c => ({
58
65
  }
59
66
  })
60
67
 
61
- /** @type {<A, T>(f: ReduceFn<A, T>) => (init: A) => (c: AsyncIterable<T>) => AsyncIterable<A>} */
68
+ /** @type {<A, T>(f: Merge<A, T>) => (init: A) => (c: AsyncIterable<T>) => AsyncIterable<A>} */
62
69
  const inclusiveScan = reduceFn => init => {
63
70
  const e = exclusiveScan(reduceFn)(init)
64
71
  return c => ({
@@ -78,10 +85,16 @@ const cast = iterable => ({
78
85
  }
79
86
  })
80
87
 
81
- /** @type {(c: AsyncIterable<number>) => Promise<number>} */
82
- const sum = reduce(a => async v => a + v)(0)
88
+ /** @type {<I, S, R>(op: mapReduce.Operation<I, S, R>) => (_: AsyncIterable<I>) => Promise<R>} */
89
+ const apply = ({ merge, init, result }) => async c => result(await reduce(merge)(init)(c))
90
+
91
+ const sum = apply(mapReduce.sum)
92
+
93
+ const join = pipe(mapReduce.join)(apply)
83
94
 
84
95
  module.exports = {
96
+ /** @readonly */
97
+ apply,
85
98
  /** @readonly */
86
99
  cast,
87
100
  /** @readonly */
@@ -95,6 +108,8 @@ module.exports = {
95
108
  /** @readonly */
96
109
  sum,
97
110
  /** @readonly */
111
+ join,
112
+ /** @readonly */
98
113
  exclusiveScan,
99
114
  /** @readonly */
100
115
  inclusiveScan,
File without changes
package/btree/index.js CHANGED
@@ -55,27 +55,37 @@ const { index3, index5 } = require('../cmp')
55
55
 
56
56
  /**
57
57
  * @template T
58
- * @typedef {Leaf1<T>|Leaf2<T>|Branch3<T>|Branch5<T>} TNode
58
+ * @typedef { Leaf1<T> | Leaf2<T> | Branch3<T> | Branch5<T>} TNode
59
+ */
60
+
61
+ /** @typedef {{ readonly done: false }} NotFoundDone */
62
+
63
+ /**
64
+ * @template T
65
+ * @typedef {{
66
+ * readonly done: true
67
+ * readonly value: T
68
+ * }} FoundDone
59
69
  */
60
70
 
61
71
  /**
62
72
  * @template T
63
- * @typedef {{ done: false } | { done: true, value: T }} Done
73
+ * @typedef { NotFoundDone | FoundDone<T> } Done
64
74
  */
65
75
 
66
76
  /**
67
77
  * @template T
68
- * @typedef {{ replace: TNode<T> }} Replace
78
+ * @typedef {{ readonly replace: TNode<T> }} Replace
69
79
  */
70
80
 
71
81
  /**
72
82
  * @template T
73
- * @typedef {{ overflow: Branch3<T> }} Overflow
83
+ * @typedef {{ readonly overflow: Branch3<T> }} Overflow
74
84
  */
75
85
 
76
86
  /**
77
87
  * @template T
78
- * @typedef {Done<T> | Replace<T> | Overflow<T>} Result
88
+ * @typedef { Done<T> | Replace<T> | Overflow<T> } Result
79
89
  */
80
90
 
81
91
  /** @typedef {<T>(_: Lazy<T>) => (_: Leaf1<T>) => Result<T>} InLeaf1 */
@@ -85,35 +95,35 @@ const { index3, index5 } = require('../cmp')
85
95
 
86
96
  /**
87
97
  * @typedef {{
88
- * leaf1: InLeaf1
89
- * leaf2_left: InLeaf2
90
- * leaf2_right: InLeaf2
91
- * branch3: InBranch3
92
- * branch5_left: InBranch5
93
- * branch5_right: InBranch5
98
+ * readonly leaf1: InLeaf1
99
+ * readonly leaf2_left: InLeaf2
100
+ * readonly leaf2_right: InLeaf2
101
+ * readonly branch3: InBranch3
102
+ * readonly branch5_left: InBranch5
103
+ * readonly branch5_right: InBranch5
94
104
  * }} Found
95
105
  */
96
106
 
97
107
  /**
98
108
  * @typedef {{
99
- * leaf1_left: InLeaf1
100
- * leaf1_right: InLeaf1
101
- * leaf2_left: InLeaf2
102
- * leaf2_middle: InLeaf2
103
- * leaf2_right: InLeaf2
109
+ * readonly leaf1_left: InLeaf1
110
+ * readonly leaf1_right: InLeaf1
111
+ * readonly leaf2_left: InLeaf2
112
+ * readonly leaf2_middle: InLeaf2
113
+ * readonly leaf2_right: InLeaf2
104
114
  * }} NotFound
105
115
  */
106
116
 
107
117
  /**
108
118
  * @typedef {{
109
- * found: Found
110
- * notFound: NotFound
119
+ * readonly found: Found
120
+ * readonly notFound: NotFound
111
121
  * }} Visitor
112
122
  */
113
123
 
114
124
  /**
115
125
  * @template T
116
- * @typedef {readonly [TNode<T>, T, TNode<T>, T, TNode<T>, T, TNode<T>]} Branch7
126
+ * @typedef { readonly [TNode<T>, T, TNode<T>, T, TNode<T>, T, TNode<T>] } Branch7
117
127
  */
118
128
 
119
129
  /** @type {<T>(n: Branch7<T>) => Branch3<T>} */
@@ -221,7 +231,7 @@ const visit = ({ found, notFound }) => cmp => {
221
231
  }
222
232
  }
223
233
 
224
- /** @type {<T>(_: T) => Done<T>} */
234
+ /** @type { <T>(_: T) => Done<T> } */
225
235
  const found = value => ({ done: true, value })
226
236
 
227
237
  /** @type {Found} */
@@ -233,7 +243,7 @@ const foundGet = {
233
243
  branch5_left: () => ([, value]) => found(value),
234
244
  branch5_right: () => ([, , , value]) => found(value),
235
245
  }
236
- /** @type {() => () => { done: false }} */
246
+ /** @type { () => () => NotFoundDone } */
237
247
  const notFound = () => () => ({ done: false })
238
248
 
239
249
  /** @type {NotFound} */
@@ -245,7 +255,7 @@ const notFoundGet = {
245
255
  leaf2_right: notFound,
246
256
  }
247
257
 
248
- /** @type {<T>(_: TNode<T>) => Replace<T>} */
258
+ /** @type { <T>(_: TNode<T>) => Replace<T> } */
249
259
  const replace = node => ({ replace: node })
250
260
 
251
261
  /** @type {Found} */
@@ -288,6 +298,7 @@ const getOrInsertVisitor = {
288
298
  notFound: notFoundInsert,
289
299
  }
290
300
 
301
+ /** @type {Visitor} */
291
302
  const replaceVisitor = {
292
303
  found: foundReplace,
293
304
  notFound: notFoundGet,
@@ -324,7 +335,7 @@ module.exports = {
324
335
  values,
325
336
  /**
326
337
  * @readonly
327
- * @type {<T>(cmp: Cmp<T>) => (node: TNode<T>) => T|undefined}
338
+ * @type { <T>(cmp: Cmp<T>) => (node: TNode<T>) => T|undefined }
328
339
  */
329
340
  getVisitor: cmp => node => {
330
341
  const result = visit(getVisitor)(cmp)(() => { throw '' })(node)
package/dev/index.js ADDED
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ /** @readonly */
3
+ todo: () => { throw 'not implemented' },
4
+ }
package/func/index.js ADDED
@@ -0,0 +1,12 @@
1
+ /** @type {<I, X>(_: (_: I) => X) => <O>(_: (_: X) => O) => (_: I) => O} */
2
+ const pipe = g => f => x => f(g(x))
3
+
4
+ /** @type {<T>(value: T) => T} */
5
+ const id = value => value
6
+
7
+ module.exports = {
8
+ /** @readonly */
9
+ id,
10
+ /** @readonly */
11
+ pipe,
12
+ }
package/index.js CHANGED
@@ -1,9 +1,3 @@
1
- "use strict";
2
-
3
- const lib = require('./lib')
4
-
5
- const todo = () => lib.panic('not implemented')
6
-
7
1
  /** @type {<F>(c: string, found: (before: string, after: string) => F, notFound: (c: string, source: string) => F) => (source: string) => F} */
8
2
  const splitOne = (c, found, notFound) => source => {
9
3
  const i = source.indexOf(c)
package/iterable/index.js CHANGED
@@ -1,5 +1,4 @@
1
- const { pipe } = require('../lib')
2
- const lib = require('../lib')
1
+ const { pipe } = require('../func')
3
2
  const mr = require('../map-reduce')
4
3
 
5
4
  /** @type {<T, R>(merge: (_: R) => (_: T) => R) => (init: R) => (_: Iterable<T>) => R} */
@@ -12,7 +11,20 @@ const reduce = merge => init => c => {
12
11
  }
13
12
 
14
13
  /** @type {<I, S, R>(op: mr.Operation<I, S, R>) => (_: Iterable<I>) => R} */
15
- const apply = op => pipe(reduce(op.reduce)(op.init))(op.result)
14
+ const apply = ({ merge, init, result }) => pipe(reduce(merge)(init))(result)
15
+
16
+ const sum = apply(mr.sum)
17
+
18
+ const join = pipe(mr.join)(apply)
19
+
20
+ /** @type {<T, R>(f: (value: T) => R) => (c: Iterable<T>) => Iterable<R>} */
21
+ const map = f => c => ({
22
+ *[Symbol.iterator]() {
23
+ for (const i of c) {
24
+ yield f(i)
25
+ }
26
+ }
27
+ })
16
28
 
17
29
  module.exports = {
18
30
  /** @readonly */
@@ -22,22 +34,13 @@ module.exports = {
22
34
  reduce,
23
35
 
24
36
  /** @readonly */
25
- join: pipe(mr.join)(apply),
37
+ join,
26
38
 
27
39
  /** @readonly */
28
- sum: apply(mr.sum),
40
+ sum,
29
41
 
30
- /**
31
- * @readonly
32
- * @type {<T, R>(f: (value: T) => R) => (c: Iterable<T>) => Iterable<R>}
33
- */
34
- map: f => c => ({
35
- *[Symbol.iterator]() {
36
- for (const i of c) {
37
- yield f(i)
38
- }
39
- }
40
- }),
42
+ /** @readonly */
43
+ map,
41
44
 
42
45
  /**
43
46
  * @readonly
package/iterable/test.js CHANGED
@@ -1,41 +1,41 @@
1
1
  const i = require('.')
2
- const lib = require('../lib')
2
+ const { pipe } = require('../func')
3
3
 
4
4
  {
5
5
  const r = i.sum([120, 300, 42])
6
- lib.panic_if('reduce')(r !== 462)
6
+ if (r !== 462) { throw 'error' }
7
7
  }
8
8
 
9
9
  {
10
- lib.panic_if('first sum')(i.sum([1, 2]) !== 3)
11
- lib.panic_if('second sum')(i.sum([1, 2]) !== 3)
10
+ if (i.sum([1, 2]) !== 3) { throw 'error' }
11
+ if (i.sum([1, 2]) !== 3) { throw 'error' }
12
12
  }
13
13
 
14
14
  {
15
15
  const x = Array.from(i.map(a => a ** 2)([1, 2, 3]))
16
- lib.panic_if('map')(x.length !== 3)
17
- lib.panic_if('map[0]')(x[0] !== 1)
18
- lib.panic_if('map[1]')(x[1] !== 4)
19
- lib.panic_if('map[2]')(x[2] !== 9)
16
+ if (x.length !== 3) { throw 'error' }
17
+ if (x[0] !== 1) { throw 'error' }
18
+ if (x[1] !== 4) { throw 'error' }
19
+ if (x[2] !== 9) { throw 'error' }
20
20
  }
21
21
 
22
22
  {
23
- lib.panic_if('join')(i.join('/')([]) !== '')
24
- lib.panic_if('join')(i.join('/')(['a']) !== 'a')
25
- lib.panic_if('join')(i.join('/')(['a', 'b']) !== 'a/b')
23
+ if (i.join('/')([]) !== '') { throw 'error' }
24
+ if (i.join('/')(['a']) !== 'a') { throw 'error' }
25
+ if (i.join('/')(['a', 'b']) !== 'a/b') { throw 'error'}
26
26
  }
27
27
 
28
28
  {
29
- lib.panic_if('find')(i.find(x => x === 'c')(['a', 'b', 'c']) !== 'c')
29
+ if (i.find(x => x === 'c')(['a', 'b', 'c']) !== 'c') { throw 'error' }
30
30
  }
31
31
 
32
32
  {
33
33
  /** @type {(_: string) => string|undefined} */
34
34
  const file = _ => 'x'
35
35
  /** @type {(_: string) => string|undefined} */
36
- const x = p => lib.pipe
36
+ const x = p => pipe
37
37
  (i.map(x => file(x())))
38
38
  (i.find(x => x !== undefined))
39
39
  ([() => p, () => `${p}.js`, () => `${p}/index.js`])
40
- lib.panic_if('map.find')(x('index.js') !== 'x')
40
+ if (x('index.js') !== 'x') { throw 'error' }
41
41
  }
package/map/index.js CHANGED
@@ -1,4 +1,4 @@
1
- const { optionMap } = require("../lib")
1
+ const option = require("../option")
2
2
  const { getVisitor, setVisitor, values } = require("../btree")
3
3
 
4
4
  /** @typedef {import("../cmp").Sign} Sign */
@@ -38,7 +38,7 @@ const cmp = a => ([b]) => a < b ? -1 : a === b ? 0 : 1
38
38
 
39
39
  /** @type {<T>(node: TNode<Entry<T>>) => Map<T>} */
40
40
  const create = root => ({
41
- get: name => optionMap(([,value]) => value)(getVisitor(cmp(name))(root)),
41
+ get: name => option.map(([,value]) => value)(getVisitor(cmp(name))(root)),
42
42
  set: name => value => {
43
43
  const result = setVisitor(cmp(name))(() => [name, value])(root)
44
44
  if ('replace' in result) { return create(result.replace) }
@@ -53,7 +53,7 @@ const create = root => ({
53
53
  * @type {{
54
54
  * readonly get: (name: string) => undefined
55
55
  * readonly set: (name: string) => <T>(value: T) => Map<T>
56
- * readonly entries: () => []
56
+ * readonly entries: () => readonly []
57
57
  * readonly root: undefined
58
58
  * }}
59
59
  */
package/map/test.js CHANGED
@@ -1,5 +1,4 @@
1
1
  const { empty } = require('.')
2
- const lib = require('../lib')
3
2
 
4
3
  {
5
4
  let m = empty.set('a')(1)
@@ -42,14 +41,13 @@ const lib = require('../lib')
42
41
 
43
42
  {
44
43
  const m = empty.set('x')(12).set('y')(44)
45
- lib.panic_if('map.get(\'x\')')(m.get('x') !== 12)
46
- lib.panic_if('map.get(\'y\')')(m.get('y') !== 44)
47
- lib.panic_if('map.get(\'a\')')(m.get('a') !== undefined)
44
+ if (m.get('x') !== 12) { throw 'error' }
45
+ if (m.get('y') !== 44) { throw 'error' }
46
+ if (m.get('a') !== undefined) { throw 'error' }
48
47
  const entries = Array.from(m.entries())
49
- lib.panic_if('map.entries()')(entries.length !== 2)
48
+ if (entries.length !== 2) { throw 'error' }
50
49
  }
51
50
 
52
-
53
51
  {
54
52
  /** @type {import('.').Map<number>} */
55
53
  let m = empty
@@ -1,34 +1,40 @@
1
- const { pipe } = require('../lib')
1
+ const { pipe, id } = require('../func')
2
+
3
+ /**
4
+ * @template S
5
+ * @template I
6
+ * @typedef {(state: S) => (value: I) => S} Merge
7
+ */
2
8
 
3
9
  /**
4
10
  * @template I
5
11
  * @template S
6
12
  * @template O
7
13
  * @typedef {{
8
- * readonly reduce: (state: S) => (value: I) => S
14
+ * readonly merge: Merge<S, I>
9
15
  * readonly result: (state: S) => O
10
16
  * readonly init: S
11
17
  * }} Operation
12
18
  */
13
19
 
14
20
  /** @type {<I, T>(mapFn: (value: I) => T) => <S, O>(op: Operation<T, S, O>) => Operation<I, S, O>} */
15
- const map = mapFn => ({ reduce, result, init}) => ({
16
- reduce: pipe(reduce)(pipe(mapFn)),
21
+ const map = mapFn => ({ merge, result, init}) => ({
22
+ merge: pipe(merge)(pipe(mapFn)),
17
23
  result,
18
24
  init,
19
25
  })
20
26
 
21
27
  /** @type {(separator: string) => Operation<string, string|undefined, string>} */
22
28
  const join = separator => ({
23
- reduce: s => i => s === undefined ? i : `${s}${separator}${i}`,
29
+ merge: s => i => s === undefined ? i : `${s}${separator}${i}`,
24
30
  init: undefined,
25
31
  result: s => s === undefined ? '' : s
26
32
  })
27
33
 
28
34
  /** @type {Operation<number, number, number>} */
29
35
  const sum = {
30
- reduce: a => i => a + i,
31
- result: a => a,
36
+ merge: a => i => a + i,
37
+ result: id,
32
38
  init: 0,
33
39
  }
34
40
 
@@ -1,86 +1,98 @@
1
- const lib = require('../lib')
1
+ const array = require('../array')
2
+ const { pipe } = require('../func')
3
+ const option = require('../option')
4
+ const { head, last, splitLast, splitFirst } = array
2
5
  const iter = require('../iterable')
3
6
  const mr = require('../map-reduce')
4
7
 
8
+ /**
9
+ * @template T
10
+ * @typedef {array.Array<T>} Array
11
+ */
12
+
13
+ /** @typedef {Array<string>} Path */
14
+
5
15
  /** @typedef {(_: string) => string|undefined} ReadFile */
6
16
 
7
17
  /**
8
18
  * @typedef {{
9
- * id: string[]
10
- * dependencies: Dependencies
11
- * file: ReadFile
19
+ * readonly id: Array<string>
20
+ * readonly dependencies: Dependencies
21
+ * readonly file: ReadFile
12
22
  * }} Package
13
23
  */
14
24
 
15
25
  /**
16
26
  * @typedef {{
17
- * pack: Package,
18
- * local: string[],
27
+ * readonly pack: Package,
28
+ * readonly local: Array<string>,
19
29
  * }} Location
20
30
  */
21
31
 
22
32
  /**
23
33
  * @typedef {{
24
- * fileName: string
25
- * location: Location
26
- * source: string
34
+ * readonly fileName: string
35
+ * readonly location: Location
36
+ * readonly source: string
27
37
  * }} Module
28
38
  */
29
39
 
30
40
  /** @typedef {(_: string) => undefined|Package|Dependencies} Dependencies */
31
41
 
32
- /** @type {mr.Operation<string, undefined|string[], undefined|string[]>} */
42
+ /** @type {mr.Operation<string, undefined|Path, undefined|Path>} */
33
43
  const pathNormReduce = {
34
- reduce: path => item =>
44
+ merge: path => item =>
35
45
  path === undefined ?
36
46
  undefined :
37
47
  ['', '.'].includes(item) ?
38
48
  path :
39
49
  item === '..' ?
40
- lib.head(path) :
50
+ head(path) :
41
51
  [...path, item],
42
52
  init: [],
43
53
  result: s => s,
44
54
  }
45
55
 
46
- /** @type {(_: string[]) => boolean} */
56
+ /** @type {(_: Array<string>) => boolean} */
47
57
  const isRelative = localId => ['.', '..'].includes(localId[0])
48
58
 
49
59
  const pathNorm = iter.apply(pathNormReduce)
50
60
 
51
- /** @type {(_: Package) => (_: string[]) => Module|undefined} */
61
+ /** @type {(_: Package) => (_: Path) => Module|undefined} */
52
62
  const internal = pack => {
53
- /** @type {(_: string[]) => (_: string) => Module|undefined} */
63
+ /** @type {(_: Path) => (_: string) => Module|undefined} */
54
64
  const readFile = local => fileName => {
55
65
  const source = pack.file([...local, fileName].join('/'))
56
66
  return source === undefined ? undefined : { fileName, location: { pack, local }, source}
57
67
  }
58
68
  return path => {
59
- /** @type {(_: string[]) => Module|undefined} */
69
+ /** @type {(_: Path) => Module|undefined} */
60
70
  const read = local => {
61
- /** @type {(_: [string[], string]) => Module|undefined} */
62
- const tryFiles = ([head, last]) => {
71
+ /** @type {(_: readonly[Path, string]) => Module|undefined} */
72
+ const tryFiles = ([head, file]) => {
63
73
  /** @type {(_: string) => Module|undefined} */
64
- const one = ext => readFile(head)(last + ext)
65
- return ['.', '..', '', undefined].includes(lib.last(path)) ? undefined : one('') ?? one('.js')
74
+ const one = ext => readFile(head)(file + ext)
75
+ return ['.', '..', '', undefined].includes(last(path)) ? undefined : one('') ?? one('.js')
66
76
  }
67
- return lib.optionMap(tryFiles)(lib.splitLast(local)) ?? readFile(local)('index.js')
77
+ return option.map(tryFiles)(splitLast(local)) ?? readFile(local)('index.js')
68
78
  }
69
- return lib.optionMap(read)(pathNorm(path))
79
+ return option.map(read)(pathNorm(path))
70
80
  }
71
81
  }
72
82
 
73
- /** @type {(_: Package|Dependencies|undefined) => (_: string[]) => Module|undefined} */
83
+ /** @type {(_: Package|Dependencies|undefined) => (_: Path) => Module|undefined} */
74
84
  const externalOrInternal = p =>
75
85
  p === undefined ? () => undefined : (typeof p === 'function' ? external(p) : internal(p))
76
86
 
77
- /** @type {(_: Dependencies) => (_: string[]) => Module|undefined} */
87
+ /** @type {(_: Dependencies) => (_: Path) => Module|undefined} */
78
88
  const external = packages => {
79
- /** @type {(_: [string, string[]]) => Module|undefined} */
89
+ /** @type {(_: readonly [string, Path]) => Module|undefined} */
80
90
  const defined = ([first, tail]) => externalOrInternal(packages(first))(tail)
81
- /** @type {(_: string[]) => [string, string[]]|undefined} */
82
- const splitFirst = lib.splitFirst
83
- return lib.pipe(splitFirst)(lib.optionMap(defined))
91
+ /** @type {(_: Path) => readonly [string, Path]|undefined} */
92
+ const sf = splitFirst
93
+ return pipe
94
+ (sf)
95
+ (option.map(defined))
84
96
  }
85
97
 
86
98
  /** @type {(_: Location) => (_: string) => Module|undefined} */
@@ -101,4 +113,4 @@ module.exports = {
101
113
  getModule,
102
114
  /** @readonly */
103
115
  moduleId,
104
- }
116
+ }
@@ -1,4 +1,3 @@
1
- const lib = require('../../lib')
2
1
  const mm = require('..')
3
2
  const i = require('.')
4
3
 
@@ -1,17 +1,18 @@
1
1
  const i = require('.')
2
2
 
3
- const lib = require('../lib')
4
-
5
3
  require('./node/test')
6
4
 
7
5
  /** @type {<T>(_: T | undefined) => T} */
8
- const cast = x => x === undefined ? lib.panic('x') : x
6
+ const cast = x => {
7
+ if (x === undefined) { throw 'x' }
8
+ return x
9
+ }
9
10
 
10
- lib.panic_if('isRelative')(i.isRelative('a/b/c'.split('/')))
11
- lib.panic_if('!isRelative')(!i.isRelative('./a/b/c'.split('/')))
12
- lib.panic_if('pathNorm')(cast(i.pathNorm('a/../b'.split('/'))).join('/') !== 'b')
13
- lib.panic_if('pathNorm')(cast(i.pathNorm('a/../b/../c'.split('/'))).join('/') !== 'c')
14
- lib.panic_if('pathNorm')(cast(i.pathNorm('./a/../b/c/..//d/'.split('/'))).join('/') !== 'b/d')
11
+ if (i.isRelative('a/b/c'.split('/'))) { throw 'error '}
12
+ if (!i.isRelative('./a/b/c'.split('/'))) { throw 'error ' }
13
+ if (cast(i.pathNorm('a/../b'.split('/'))).join('/') !== 'b') { throw 'error ' }
14
+ if (cast(i.pathNorm('a/../b/../c'.split('/'))).join('/') !== 'c') { throw 'error ' }
15
+ if (cast(i.pathNorm('./a/../b/c/..//d/'.split('/'))).join('/') !== 'b/d') { throw 'error ' }
15
16
 
16
17
  {
17
18
  /** @type {i.Package} */
@@ -35,7 +36,8 @@ lib.panic_if('pathNorm')(cast(i.pathNorm('./a/../b/c/..//d/'.split('/'))).join('
35
36
  'index.js': 'b/c ./index.js',
36
37
  'x/index.js': 'b/c ./x/index.js',
37
38
  }
38
- return ['.js', '', 'undefined.js'].includes(path) ? lib.panic('.js') : f[path]
39
+ if (['.js', '', 'undefined.js'].includes(path)) { throw '.js' }
40
+ return f[path]
39
41
  },
40
42
  id: ['c']
41
43
  }
@@ -59,7 +61,8 @@ lib.panic_if('pathNorm')(cast(i.pathNorm('./a/../b/c/..//d/'.split('/'))).join('
59
61
  'a/index.js': './a/index.js',
60
62
  'a/index.js.js': './a/index.js.js',
61
63
  }
62
- return ['.js', '', 'undefined.js'].includes(path) ? lib.panic('.js') : f[path]
64
+ if (['.js', '', 'undefined.js'].includes(path)) { throw '.js' }
65
+ return f[path]
63
66
  },
64
67
  id: ['']
65
68
  }
@@ -72,8 +75,8 @@ lib.panic_if('pathNorm')(cast(i.pathNorm('./a/../b/c/..//d/'.split('/'))).join('
72
75
  }
73
76
  {
74
77
  const g = i.getModule({pack, local: []})
75
- lib.panic_if('getModule')(g('') !== undefined)
76
- lib.panic_if('getModule')(g('..') !== undefined)
78
+ if (g('') !== undefined) { throw 'error' }
79
+ if (g('..') !== undefined) { throw 'error' }
77
80
  expect(g('.'))({ fileName: 'index.js', location: { pack, local: []}, source: './index.js'})
78
81
  expect(g('./index'))({ fileName: 'index.js', location: { pack, local: []}, source: './index.js'})
79
82
  expect(g('./index.js'))({ fileName: 'index.js', location: { pack, local: []}, source: './index.js'})
@@ -81,10 +84,10 @@ lib.panic_if('pathNorm')(cast(i.pathNorm('./a/../b/c/..//d/'.split('/'))).join('
81
84
  expect(g('./a'))({ fileName: 'index.js', location: { pack, local: ['a']}, source: './a/index.js'})
82
85
  expect(g('./a/index'))({ fileName: 'index.js', location: { pack, local: ['a']}, source: './a/index.js'})
83
86
  expect(g('./a/index.js'))({ fileName: 'index.js.js', location: { pack, local: ['a']}, source: './a/index.js'})
84
- lib.panic_if('getModule')(g('./x') !== undefined)
87
+ if (g('./x') !== undefined) { throw 'error' }
85
88
  expect(g('a'))({ fileName: 'index.js', location: { pack: a, local: []}, source: 'a ./index.js'})
86
89
  expect(g('a/index'))({ fileName: 'index.js', location: { pack: a, local: []}, source: 'a ./index.js'})
87
- lib.panic_if('getModule')(g('b') !== undefined)
90
+ if (g('b') !== undefined) { throw 'error' }
88
91
  expect(g('b/c'))({ fileName: 'index.js', location: { pack: c, local: []}, source: 'b/c ./index.js'})
89
92
  expect(g('b/c/index'))({ fileName: 'index.js', location: { pack: c, local: []}, source: 'b/c ./index.js'})
90
93
  expect(g('b/c/index.js'))({ fileName: 'index.js', location: { pack: c, local: []}, source: 'b/c ./index.js'})
@@ -93,21 +96,21 @@ lib.panic_if('pathNorm')(cast(i.pathNorm('./a/../b/c/..//d/'.split('/'))).join('
93
96
  }
94
97
  {
95
98
  const g = i.getModule({pack, local: ['index']})
96
- lib.panic_if('getModule')(g('') !== undefined)
99
+ if (g('') !== undefined) { throw 'error' }
97
100
  expect(g('..'))({ fileName: 'index.js', location: { pack, local: []}, source: './index.js'})
98
101
  expect(g('.'))({ fileName: 'index.js', location: { pack, local: ['index']}, source: './index/index.js'})
99
102
  expect(g('./index'))({ fileName: 'index.js', location: { pack, local: ['index']}, source: './index/index.js'})
100
103
  expect(g('./index.js'))({ fileName: 'index.js', location: { pack, local: ['index']}, source: './index/index.js'})
101
- lib.panic_if('getModule')(g('./index/') !== undefined)
102
- lib.panic_if('getModule')(g('./a') !== undefined)
104
+ if (g('./index/') !== undefined) { throw 'error' }
105
+ if (g('./a') !== undefined) { throw 'error' }
103
106
  expect(g('../a'))({ fileName: 'index.js', location: { pack, local: ['a']}, source: './a/index.js'})
104
107
  expect(g('../a/index'))({ fileName: 'index.js', location: { pack, local: ['a']}, source: './a/index.js'})
105
108
  expect(g('../a/index.js'))({ fileName: 'index.js', location: { pack, local: ['a']}, source: './a/index.js'})
106
109
  expect(g('../a/index.js.js'))({ fileName: 'index.js.js', location: { pack, local: ['a']}, source: './a/index.js.js'})
107
- lib.panic_if('getModule')(g('./x') !== undefined)
110
+ if (g('./x') !== undefined) { throw 'error' }
108
111
  expect(g('a'))({ fileName: 'index.js', location: { pack: a, local: []}, source: 'a ./index.js'})
109
112
  expect(g('a/index'))({ fileName: 'index.js', location: { pack: a, local: []}, source: 'a ./index.js'})
110
- lib.panic_if('getModule')(g('b') !== undefined)
113
+ if (g('b') !== undefined) { throw 'error' }
111
114
  expect(g('b/c'))({ fileName: 'index.js', location: { pack: c, local: []}, source: 'b/c ./index.js'})
112
115
  expect(g('b/c/index'))({ fileName: 'index.js', location: { pack: c, local: []}, source: 'b/c ./index.js'})
113
116
  expect(g('b/c/index.js'))({ fileName: 'index.js', location: { pack: c, local: []}, source: 'b/c ./index.js'})
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @template T
3
+ * @typedef {T|undefined} Option
4
+ */
5
+
6
+ /** @type {<T, R>(_: (_: T) => R) => (_: T|undefined) => R|undefined} */
7
+ const map = f => x => x === undefined ? undefined : f(x)
8
+
9
+ module.exports = {
10
+ /** @readonly */
11
+ map,
12
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.156",
3
+ "version": "0.0.163",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/test.js CHANGED
@@ -1,15 +1,13 @@
1
- const lib = require('./lib')
2
1
  const i = require('./')
3
2
 
4
- require('./async/test')
3
+ require('./async/iterable/test')
5
4
  require('./module-manager/test')
6
- require('./lib/test')
7
5
 
8
6
  /** @type {() => never} */
9
- const assert = () => lib.panic('assert')
7
+ const assert = () => { throw 'assert' }
10
8
 
11
9
  /** @type {(_: boolean) => void} */
12
- const assert_if = c => lib.panic_if('assert_if')(c)
10
+ const assert_if = c => { if (c) { throw 'assert_if' } }
13
11
 
14
12
  {
15
13
  i.parseModuleUrl('')(
package/lib/index.js DELETED
@@ -1,124 +0,0 @@
1
- "use strict";
2
-
3
- /**
4
- * @template T
5
- * @typedef {T|undefined} Option
6
- */
7
-
8
- /**
9
- * @template T
10
- * @typedef {() => NotEmptySequence<T>|undefined} Sequence
11
- */
12
-
13
- /**
14
- * @template T
15
- * @typedef {{ first: T, tail: Sequence<T>}} NotEmptySequence
16
- */
17
-
18
- /**
19
- * @template T
20
- * @typedef {() => Continuation<T>} Continue
21
- */
22
-
23
- /**
24
- * @template T
25
- * @typedef {[T]|Continue<T>} Continuation
26
- */
27
-
28
- /** @type {(_: string) => never} */
29
- const panic = message => { throw message }
30
-
31
- /**
32
- * @template T
33
- * @template R
34
- * @typedef {{
35
- * merge: (_: R) => (_: T) => R
36
- * init: R
37
- * }} Reduce
38
- */
39
-
40
- /** @type {<I, X>(_: (_: I) => X) => <O>(_: (_: X) => O) => (_: I) => O} */
41
- const pipe = g => f => x => f(g(x))
42
-
43
- /** @type {<T, R>(_: (_: T) => R) => (_: T|undefined) => R|undefined} */
44
- const optionMap = f => x => x === undefined ? undefined : f(x)
45
-
46
- /** @type {<T>(_: T[]) => T[]} */
47
- const uncheckTail = a => a.slice(1)
48
-
49
- /** @type {<T>(_: T[]) => T[]} */
50
- const uncheckHead = a => a.slice(0, -1)
51
-
52
- /** @type {<T>(_: T[]) => T|undefined} */
53
- const last = a => a[a.length - 1]
54
-
55
- /**
56
- * @template I
57
- * @typedef {{
58
- * readonly i: <O>(f: (input: I) => O) => Chain<O>
59
- * readonly result: () => I
60
- * }} Chain
61
- */
62
-
63
- /** @type {<I>(value: I) => Chain<I>} */
64
- const chain = value => ({
65
- i: f => chain(f(value)),
66
- result: () => value
67
- })
68
-
69
- /**
70
- * @template I
71
- * @template T
72
- * @typedef {{
73
- * readonly x: <O>(f: (v: T) => O) => Pipe<I, O>
74
- * readonly f: (input: I) => T
75
- * }} Pipe
76
- */
77
-
78
- module.exports = {
79
-
80
- panic,
81
-
82
- todo: () => panic('not implemented'),
83
-
84
- /** @type {(_: string) => (_: boolean) => void} */
85
- panic_if: message => condition => condition ? panic(message) : undefined,
86
-
87
- /** @type {<T>(_: Continuation<T>) => T} */
88
- trampoline: continuation => {
89
- while (true) {
90
- if (typeof continuation !== 'function') {
91
- return continuation[0]
92
- }
93
- continuation = continuation()
94
- }
95
- },
96
-
97
- pipe,
98
-
99
- last,
100
-
101
- optionMap,
102
-
103
- /** @type {<T>(_: T[]) => T[]|undefined} */
104
- tail: a => a.length === 0 ? undefined : uncheckTail(a),
105
-
106
- /** @type {<T>(_: T[]) => [T, T[]]|undefined} */
107
- splitFirst: a => {
108
- /** @typedef {typeof a[0]} T*/
109
- /** @type {(_: T) => [T, T[]]} */
110
- const split = first => [first, uncheckTail(a)]
111
- return optionMap(split)(a[0])
112
- },
113
-
114
- /** @type {<T>(_: T[]) => T[]|undefined} */
115
- head: a => a.length === 0 ? undefined : uncheckHead(a),
116
-
117
- /** @type {<T>(_: T[]) => [T[], T]|undefined} */
118
- splitLast: a => {
119
- /** @typedef {typeof a[0]} T*/
120
- /** @type {(_: T) => [T[], T]} */
121
- const split = x => [uncheckHead(a), x]
122
- return optionMap(split)(last(a))
123
- },
124
- }
package/lib/test.js DELETED
@@ -1,5 +0,0 @@
1
- const lib = require('./index')
2
-
3
- require('../iterable/test')
4
- require('../map/test')
5
-