functionalscript 0.0.164 → 0.0.166

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
@@ -17,6 +17,12 @@ const option = require('../option')
17
17
  * @typedef {readonly [T, T]} Array2
18
18
  */
19
19
 
20
+ /**
21
+ * @template T0
22
+ * @template T1
23
+ * @typedef {readonly [T0, T1]} Tuple2
24
+ */
25
+
20
26
  /** @typedef {0|1} Index2 */
21
27
 
22
28
  /**
@@ -1,5 +1,5 @@
1
1
  const { pipe } = require('../../func')
2
- const mapReduce = require('../../map-reduce')
2
+ const mr = require('../../map-reduce')
3
3
 
4
4
  /**
5
5
  * @template T
@@ -12,7 +12,12 @@ const mapReduce = require('../../map-reduce')
12
12
  * @typedef {(f: (value: T) => PromiseOrValue<R>) => (c: AsyncIterable<T>) => AsyncIterable<R>} Map
13
13
  */
14
14
 
15
- /** @type {<T, R>(f: (value: T) => PromiseOrValue<R>) => (c: AsyncIterable<T>) => AsyncIterable<R>} */
15
+ /**
16
+ * @template T
17
+ * @typedef {Iterable<T> | AsyncIterable<T>} AnyIterator
18
+ */
19
+
20
+ /** @type {<T, R>(f: (value: T) => PromiseOrValue<R>) => (c: AnyIterator<T>) => AsyncIterable<R>} */
16
21
  const map = f => c => ({
17
22
  async *[Symbol.asyncIterator]() {
18
23
  for await (const i of c) {
@@ -21,7 +26,7 @@ const map = f => c => ({
21
26
  }
22
27
  })
23
28
 
24
- /** @type {<T>(c: AsyncIterable<AsyncIterable<T>>) => AsyncIterable<T>} */
29
+ /** @type {<T>(c: AnyIterator<AnyIterator<T>>) => AsyncIterable<T>} */
25
30
  const flatten = c => ({
26
31
  async *[Symbol.asyncIterator]() {
27
32
  for await (const i of c) {
@@ -30,7 +35,7 @@ const flatten = c => ({
30
35
  }
31
36
  })
32
37
 
33
- /** @type {<T>(f: (value: T) => Promise<boolean>) => (c: AsyncIterable<T>) => AsyncIterable<T>} */
38
+ /** @type {<T>(f: (value: T) => Promise<boolean>) => (c: AnyIterator<T>) => AnyIterator<T>} */
34
39
  const filter = f => c => ({
35
40
  async *[Symbol.asyncIterator]() {
36
41
  for await (const i of c) {
@@ -41,7 +46,7 @@ const filter = f => c => ({
41
46
  }
42
47
  })
43
48
 
44
- /** @type {<T, R>(f: (value: T) => AsyncIterable<R>) => (c: AsyncIterable<T>) => AsyncIterable<R>} */
49
+ /** @type {<T, R>(f: (value: T) => AnyIterator<R>) => (c: AnyIterator<T>) => AsyncIterable<R>} */
45
50
  const flatMap = f => pipe(map(f))(flatten)
46
51
 
47
52
  /**
@@ -50,7 +55,7 @@ const flatMap = f => pipe(map(f))(flatten)
50
55
  * @typedef {(accumulator: A) => (value: T) => PromiseOrValue<A>} Merge
51
56
  */
52
57
 
53
- /** @type {<A, T>(merge: Merge<A, T>) => (init: A) => (c: AsyncIterable<T>) => Promise<A>} */
58
+ /** @type {<A, T>(merge: Merge<A, T>) => (init: A) => (c: AnyIterator<T>) => Promise<A>} */
54
59
  const reduce = merge => init => async c => {
55
60
  let result = init
56
61
  for await (const i of c) {
@@ -59,7 +64,15 @@ const reduce = merge => init => async c => {
59
64
  return result
60
65
  }
61
66
 
62
- /** @type {<A, T>(merg: Merge<A, T>) => (init: A) => (c: AsyncIterable<T>) => AsyncIterable<A>} */
67
+ /** @type {<T>(a: AnyIterator<T>) => (b: AnyIterator<T>) => AsyncIterable<T>} */
68
+ const concat = a => b => ({
69
+ async *[Symbol.asyncIterator]() {
70
+ yield* a
71
+ yield* b
72
+ }
73
+ })
74
+
75
+ /** @type {<A, T>(merg: Merge<A, T>) => (init: A) => (c: AnyIterator<T>) => AsyncIterable<A>} */
63
76
  const exclusiveScan = merge => init => c => ({
64
77
  async *[Symbol.asyncIterator]() {
65
78
  let result = init
@@ -70,38 +83,23 @@ const exclusiveScan = merge => init => c => ({
70
83
  }
71
84
  })
72
85
 
73
- /** @type {<A, T>(merge: Merge<A, T>) => (init: A) => (c: AsyncIterable<T>) => AsyncIterable<A>} */
74
- const inclusiveScan = merge => init => {
75
- const e = exclusiveScan(merge)(init)
76
- return c => ({
77
- async *[Symbol.asyncIterator]() {
78
- yield init
79
- yield *e(c)
80
- }
81
- })
82
- }
83
-
84
- /** @type {<T>(iterable: Iterable<T>) => AsyncIterable<T>} */
85
- const cast = iterable => ({
86
- async *[Symbol.asyncIterator]() {
87
- for (const i of iterable) {
88
- yield i
89
- }
90
- }
91
- })
86
+ /** @type {<A, T>(merge: Merge<A, T>) => (init: A) => (c: AnyIterator<T>) => AsyncIterable<A>} */
87
+ const inclusiveScan = merge => init => c => concat([init])(exclusiveScan(merge)(init)(c))
92
88
 
93
- /** @type {<I, S, R>(op: mapReduce.Operation<I, S, R>) => (_: AsyncIterable<I>) => Promise<R>} */
89
+ /** @type {<I, S, R>(op: mr.Operation<I, S, R>) => (_: AnyIterator<I>) => Promise<R>} */
94
90
  const apply = ({ merge, init, result }) => async c => result(await reduce(merge)(init)(c))
95
91
 
96
- const sum = apply(mapReduce.sum)
92
+ const sum = apply(mr.sum)
97
93
 
98
- const join = pipe(mapReduce.join)(apply)
94
+ const join = pipe(mr.join)(apply)
95
+
96
+ const size = apply(mr.size)
99
97
 
100
98
  module.exports = {
101
99
  /** @readonly */
102
100
  apply,
103
101
  /** @readonly */
104
- cast,
102
+ concat,
105
103
  /** @readonly */
106
104
  map,
107
105
  /** @readonly */
@@ -113,6 +111,8 @@ module.exports = {
113
111
  /** @readonly */
114
112
  sum,
115
113
  /** @readonly */
114
+ size,
115
+ /** @readonly */
116
116
  join,
117
117
  /** @readonly */
118
118
  exclusiveScan,
@@ -1,21 +1,21 @@
1
- const { cast, map, filter, flatMap, sum } = require('.')
1
+ const { map, filter, flatMap, sum } = require('.')
2
2
 
3
3
  const test = async () => {
4
4
  {
5
- const a = cast([1, 2, 3])
5
+ const a = [1, 2, 3]
6
6
  const m = map(async x => x * x)(a)
7
7
  const result = await sum(m)
8
8
  if (result !== 14) { throw 'filter' }
9
9
  }
10
10
  {
11
- const a = cast([1, 2, 3, 4])
11
+ const a = [1, 2, 3, 4]
12
12
  const f = filter(async x => x !== 2)(a)
13
13
  const result = await sum(f)
14
14
  if (result !== 8) { throw 'filter' }
15
15
  }
16
16
  {
17
- const a = cast([1, 2])
18
- const f = flatMap(x => cast([x, x * x]))(a)
17
+ const a = [1, 2]
18
+ const f = flatMap(x => [x, x * x])(a)
19
19
  const result = await sum(f)
20
20
  if (result !== 8) { throw 'filter' }
21
21
  }
package/iterable/index.js CHANGED
@@ -1,7 +1,13 @@
1
1
  const { pipe } = require('../func')
2
2
  const mr = require('../map-reduce')
3
3
 
4
- /** @type {<T, R>(merge: (_: R) => (_: T) => R) => (init: R) => (_: Iterable<T>) => R} */
4
+ /**
5
+ * @template S
6
+ * @template T
7
+ * @typedef {(_: S) => (_: T) => S} Merge
8
+ */
9
+
10
+ /** @type {<T, R>(merge: Merge<R, T>) => (init: R) => (_: Iterable<T>) => R} */
5
11
  const reduce = merge => init => c => {
6
12
  let result = init
7
13
  for (const i of c) {
@@ -10,11 +16,49 @@ const reduce = merge => init => c => {
10
16
  return result
11
17
  }
12
18
 
19
+ /** @type {<T>(a: Iterable<T>) => (b: Iterable<T>) => Iterable<T>} */
20
+ const concat = a => b => ({
21
+ *[Symbol.iterator]() {
22
+ yield *a
23
+ yield *b
24
+ }
25
+ })
26
+
27
+ /** @type {<A, T>(merge: Merge<A, T>) => (init: A) => (c: Iterable<T>) => Iterable<A>} */
28
+ const exclusiveScan = merge => init => c => ({
29
+ *[Symbol.iterator]() {
30
+ let result = init
31
+ for (const i of c) {
32
+ result = merge(result)(i)
33
+ yield result
34
+ }
35
+ }
36
+ })
37
+
38
+ /** @type {<A, T>(merge: Merge<A, T>) => (init: A) => (c: Iterable<T>) => Iterable<A>} */
39
+ const inclusiveScan = merge => init => c => concat([init])(exclusiveScan(merge)(init)(c))
40
+
41
+ /** @type {<T, R>(es: mr.ExlusiveScan<T, R>) => (c: Iterable<T>) => Iterable<R>} */
42
+ const applyExclusiveScan = es => c => ({
43
+ *[Symbol.iterator]() {
44
+ let ies = es
45
+ for (const i of c) {
46
+ const result = ies(i)
47
+ ies = result[1]
48
+ yield result[0]
49
+ }
50
+ }
51
+ })
52
+
53
+ const entries = applyExclusiveScan(mr.entries)
54
+
13
55
  /** @type {<I, S, R>(op: mr.Operation<I, S, R>) => (_: Iterable<I>) => R} */
14
56
  const apply = ({ merge, init, result }) => pipe(reduce(merge)(init))(result)
15
57
 
16
58
  const sum = apply(mr.sum)
17
59
 
60
+ const size = apply(mr.size)
61
+
18
62
  const join = pipe(mr.join)(apply)
19
63
 
20
64
  /** @type {<T, R>(f: (value: T) => R) => (c: Iterable<T>) => Iterable<R>} */
@@ -26,6 +70,16 @@ const map = f => c => ({
26
70
  }
27
71
  })
28
72
 
73
+ /** @type {<T>(_: (_: T) => boolean) => (_: Iterable<T>) => T|undefined} */
74
+ const find = f => c => {
75
+ for (const i of c) {
76
+ if (f(i)) {
77
+ return i
78
+ }
79
+ }
80
+ return undefined
81
+ }
82
+
29
83
  module.exports = {
30
84
  /** @readonly */
31
85
  apply,
@@ -39,19 +93,21 @@ module.exports = {
39
93
  /** @readonly */
40
94
  sum,
41
95
 
96
+ /** @readonly */
97
+ size,
98
+
99
+ /** @readonly */
100
+ entries,
101
+
42
102
  /** @readonly */
43
103
  map,
44
104
 
45
- /**
46
- * @readonly
47
- * @type {<T>(_: (_: T) => boolean) => (_: Iterable<T>) => T|undefined}
48
- */
49
- find: f => c => {
50
- for (const i of c) {
51
- if (f(i)) {
52
- return i
53
- }
54
- }
55
- return undefined
56
- }
105
+ /** @readonly */
106
+ exclusiveScan,
107
+
108
+ /** @readonly */
109
+ inclusiveScan,
110
+
111
+ /** @readonly */
112
+ find,
57
113
  }
package/iterable/test.js CHANGED
@@ -38,4 +38,14 @@ const { pipe } = require('../func')
38
38
  (i.find(x => x !== undefined))
39
39
  ([() => p, () => `${p}.js`, () => `${p}/index.js`])
40
40
  if (x('index.js') !== 'x') { throw 'error' }
41
+ }
42
+
43
+ {
44
+ const x = JSON.stringify(Array.from(i.entries(['a', 'b', 'c'])))
45
+ if (x !== '[[0,"a"],[1,"b"],[2,"c"]]') { throw x }
46
+ }
47
+
48
+ {
49
+ const x = JSON.stringify(Array.from(i.entries([])))
50
+ if (x !== '[]') { throw x }
41
51
  }
@@ -38,6 +38,35 @@ const sum = {
38
38
  init: 0,
39
39
  }
40
40
 
41
+ /**
42
+ * @type {{
43
+ * readonly merge: (counter: number) => () => number
44
+ * readonly result: (counter: number) => number
45
+ * readonly init: number
46
+ * }}
47
+ */
48
+ const size = {
49
+ merge: counter => () => counter + 1,
50
+ init: 0,
51
+ result: id,
52
+ }
53
+
54
+ /**
55
+ * @template T
56
+ * @template R
57
+ * @typedef {(value: T) => readonly [R, ExlusiveScan<T, R>]} ExlusiveScan
58
+ */
59
+
60
+ /**
61
+ * @template T
62
+ * @typedef {readonly[number, T]} Entry
63
+ */
64
+
65
+ /** @type {(index: number) => <T>(value: T) => readonly[Entry<T>, ExlusiveScan<T, Entry<T>>]} */
66
+ const entriesFrom = index => value => [[index, value], entriesFrom(index + 1)]
67
+
68
+ const entries = entriesFrom(0)
69
+
41
70
  module.exports = {
42
71
  /** @readonly */
43
72
  map,
@@ -45,4 +74,8 @@ module.exports = {
45
74
  join,
46
75
  /** @readonly */
47
76
  sum,
77
+ /** @readonly */
78
+ size,
79
+ /** @readonly */
80
+ entries,
48
81
  }
@@ -3,7 +3,6 @@ const { pipe } = require('../func')
3
3
  const option = require('../option')
4
4
  const { head, last, splitLast, splitFirst } = array
5
5
  const iter = require('../iterable')
6
- const mr = require('../map-reduce')
7
6
 
8
7
  /**
9
8
  * @template T
@@ -39,7 +38,7 @@ const mr = require('../map-reduce')
39
38
 
40
39
  /** @typedef {(_: string) => undefined|Package|Dependencies} Dependencies */
41
40
 
42
- /** @type {mr.Operation<string, undefined|Path, undefined|Path>} */
41
+ /** @type {import('../map-reduce').Operation<string, undefined|Path, undefined|Path>} */
43
42
  const pathNormReduce = {
44
43
  merge: path => item =>
45
44
  path === undefined ?
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.164",
3
+ "version": "0.0.166",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/test.js CHANGED
@@ -1,5 +1,6 @@
1
1
  const i = require('./')
2
2
 
3
+ require('./iterable/test')
3
4
  require('./async/iterable/test')
4
5
  require('./module-manager/test')
5
6