functionalscript 0.0.162 → 0.0.167

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,13 +1,23 @@
1
- const { todo } = require('../../dev')
2
- const { pipe } = require('../../func')
3
- const mapReduce = require('../../map-reduce')
1
+ const { pipe } = require('../../function')
2
+ const seq = require('../../sequence')
4
3
 
5
4
  /**
6
5
  * @template T
7
6
  * @typedef {Promise<T>|T} PromiseOrValue
8
7
  */
9
8
 
10
- /** @type {<T, R>(f: (value: T) => PromiseOrValue<R>) => (c: AsyncIterable<T>) => AsyncIterable<R>} */
9
+ /**
10
+ * @template T
11
+ * @template R
12
+ * @typedef {(f: (value: T) => PromiseOrValue<R>) => (c: AsyncIterable<T>) => AsyncIterable<R>} Map
13
+ */
14
+
15
+ /**
16
+ * @template T
17
+ * @typedef {Iterable<T> | AsyncIterable<T>} AnyIterable
18
+ */
19
+
20
+ /** @type {<T, R>(f: (value: T) => PromiseOrValue<R>) => (c: AnyIterable<T>) => AsyncIterable<R>} */
11
21
  const map = f => c => ({
12
22
  async *[Symbol.asyncIterator]() {
13
23
  for await (const i of c) {
@@ -16,7 +26,7 @@ const map = f => c => ({
16
26
  }
17
27
  })
18
28
 
19
- /** @type {<T>(c: AsyncIterable<AsyncIterable<T>>) => AsyncIterable<T>} */
29
+ /** @type {<T>(c: AnyIterable<AnyIterable<T>>) => AsyncIterable<T>} */
20
30
  const flatten = c => ({
21
31
  async *[Symbol.asyncIterator]() {
22
32
  for await (const i of c) {
@@ -25,7 +35,7 @@ const flatten = c => ({
25
35
  }
26
36
  })
27
37
 
28
- /** @type {<T>(f: (value: T) => Promise<boolean>) => (c: AsyncIterable<T>) => AsyncIterable<T>} */
38
+ /** @type {<T>(f: (value: T) => Promise<boolean>) => (c: AnyIterable<T>) => AnyIterable<T>} */
29
39
  const filter = f => c => ({
30
40
  async *[Symbol.asyncIterator]() {
31
41
  for await (const i of c) {
@@ -36,7 +46,7 @@ const filter = f => c => ({
36
46
  }
37
47
  })
38
48
 
39
- /** @type {<T, R>(f: (value: T) => AsyncIterable<R>) => (c: AsyncIterable<T>) => AsyncIterable<R>} */
49
+ /** @type {<T, R>(f: (value: T) => AnyIterable<R>) => (c: AnyIterable<T>) => AsyncIterable<R>} */
40
50
  const flatMap = f => pipe(map(f))(flatten)
41
51
 
42
52
  /**
@@ -45,7 +55,7 @@ const flatMap = f => pipe(map(f))(flatten)
45
55
  * @typedef {(accumulator: A) => (value: T) => PromiseOrValue<A>} Merge
46
56
  */
47
57
 
48
- /** @type {<A, T>(f: Merge<A, T>) => (init: A) => (c: AsyncIterable<T>) => Promise<A>} */
58
+ /** @type {<A, T>(merge: Merge<A, T>) => (init: A) => (c: AnyIterable<T>) => Promise<A>} */
49
59
  const reduce = merge => init => async c => {
50
60
  let result = init
51
61
  for await (const i of c) {
@@ -54,47 +64,54 @@ const reduce = merge => init => async c => {
54
64
  return result
55
65
  }
56
66
 
57
- /** @type {<A, T>(f: Merge<A, T>) => (init: A) => (c: AsyncIterable<T>) => AsyncIterable<A>} */
58
- const exclusiveScan = reduceFn => init => c => ({
67
+ /** @type {<T>(a: AnyIterable<T>) => (b: AnyIterable<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: AnyIterable<T>) => AsyncIterable<A>} */
76
+ const exclusiveScan = merge => init => c => ({
59
77
  async *[Symbol.asyncIterator]() {
60
78
  let result = init
61
79
  for await (const i of c) {
62
- result = await reduceFn(result)(i)
80
+ result = await merge(result)(i)
63
81
  yield result
64
82
  }
65
83
  }
66
84
  })
67
85
 
68
- /** @type {<A, T>(f: Merge<A, T>) => (init: A) => (c: AsyncIterable<T>) => AsyncIterable<A>} */
69
- const inclusiveScan = reduceFn => init => {
70
- const e = exclusiveScan(reduceFn)(init)
71
- return c => ({
72
- async *[Symbol.asyncIterator]() {
73
- yield init
74
- yield *e(c)
75
- }
76
- })
77
- }
78
-
79
- /** @type {<T>(iterable: Iterable<T>) => AsyncIterable<T>} */
80
- const cast = iterable => ({
86
+ /** @type {<T, R>(es: seq.ExlusiveScan<T, R>) => (c: AnyIterable<T>) => AsyncIterable<R>} */
87
+ const applyExclusiveScan = es => c => ({
81
88
  async *[Symbol.asyncIterator]() {
82
- for (const i of iterable) {
83
- yield i
89
+ let ies = es
90
+ for await (const i of c) {
91
+ const result = ies(i)
92
+ ies = result[1]
93
+ yield result[0]
84
94
  }
85
95
  }
86
96
  })
87
97
 
88
- /** @type {<I, S, R>(op: mapReduce.Operation<I, S, R>) => (_: AsyncIterable<I>) => Promise<R>} */
98
+ /** @type {<A, T>(merge: Merge<A, T>) => (init: A) => (c: AnyIterable<T>) => AsyncIterable<A>} */
99
+ const inclusiveScan = merge => init => c => concat([init])(exclusiveScan(merge)(init)(c))
100
+
101
+ /** @type {<I, S, R>(op: seq.Operation<I, S, R>) => (_: AnyIterable<I>) => Promise<R>} */
89
102
  const apply = ({ merge, init, result }) => async c => result(await reduce(merge)(init)(c))
90
103
 
91
- const sum = apply(mapReduce.sum)
104
+ const sum = apply(seq.sum)
105
+
106
+ const join = pipe(seq.join)(apply)
107
+
108
+ const size = apply(seq.size)
92
109
 
93
110
  module.exports = {
94
111
  /** @readonly */
95
112
  apply,
96
113
  /** @readonly */
97
- cast,
114
+ concat,
98
115
  /** @readonly */
99
116
  map,
100
117
  /** @readonly */
@@ -106,6 +123,10 @@ module.exports = {
106
123
  /** @readonly */
107
124
  sum,
108
125
  /** @readonly */
126
+ size,
127
+ /** @readonly */
128
+ join,
129
+ /** @readonly */
109
130
  exclusiveScan,
110
131
  /** @readonly */
111
132
  inclusiveScan,
@@ -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
  }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @template I
3
+ * @template O
4
+ * @typedef {(_: I) => O} Func
5
+ */
6
+
7
+ /** @type {<X, O>(f: Func<X, O>) => <I>(g: Func<I, X>) => Func<I, O>} */
8
+ const combine = f => g => x => f(g(x))
9
+
10
+ /** @type {<I, X>(g: Func<I, X>) => <O>(g: Func<X, O>) => Func<I, O>} */
11
+ const pipe = g => f => x => f(g(x))
12
+
13
+ /** @type {<T>(value: T) => T} */
14
+ const id = value => value
15
+
16
+ /**
17
+ * @template I
18
+ * @template O
19
+ * @typedef {{
20
+ * readonly pipe: <R>(f: Func<O, R>) => Pipe<I, R>
21
+ * readonly call: Func<I, O>
22
+ * }} Pipe
23
+ */
24
+
25
+ /** @type {<I, O>(f: Func<I, O>) => Pipe<I, O>} */
26
+ const pipex = call => ({
27
+ pipe: f => pipex(pipe(call)(f)),
28
+ call,
29
+ })
30
+
31
+ module.exports = {
32
+ /** @readonly */
33
+ id,
34
+ /** @readonly */
35
+ pipe,
36
+ /** @readonly */
37
+ combine,
38
+ /** @readonly */
39
+ pipex,
40
+ }
package/iterable/index.js CHANGED
@@ -1,7 +1,13 @@
1
- const { pipe } = require('../func')
2
- const mr = require('../map-reduce')
1
+ const { pipe } = require('../function')
2
+ const seq = require('../sequence')
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,9 +16,70 @@ const reduce = merge => init => c => {
10
16
  return result
11
17
  }
12
18
 
13
- /** @type {<I, S, R>(op: mr.Operation<I, S, R>) => (_: Iterable<I>) => R} */
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: seq.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(seq.entries)
54
+
55
+ /** @type {<I, S, R>(op: seq.Operation<I, S, R>) => (_: Iterable<I>) => R} */
14
56
  const apply = ({ merge, init, result }) => pipe(reduce(merge)(init))(result)
15
57
 
58
+ const sum = apply(seq.sum)
59
+
60
+ const size = apply(seq.size)
61
+
62
+ const join = pipe(seq.join)(apply)
63
+
64
+ /** @type {<T, R>(f: (value: T) => R) => (c: Iterable<T>) => Iterable<R>} */
65
+ const map = f => c => ({
66
+ *[Symbol.iterator]() {
67
+ for (const i of c) {
68
+ yield f(i)
69
+ }
70
+ }
71
+ })
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
+
16
83
  module.exports = {
17
84
  /** @readonly */
18
85
  apply,
@@ -21,33 +88,26 @@ module.exports = {
21
88
  reduce,
22
89
 
23
90
  /** @readonly */
24
- join: pipe(mr.join)(apply),
91
+ join,
25
92
 
26
93
  /** @readonly */
27
- sum: apply(mr.sum),
94
+ sum,
28
95
 
29
- /**
30
- * @readonly
31
- * @type {<T, R>(f: (value: T) => R) => (c: Iterable<T>) => Iterable<R>}
32
- */
33
- map: f => c => ({
34
- *[Symbol.iterator]() {
35
- for (const i of c) {
36
- yield f(i)
37
- }
38
- }
39
- }),
96
+ /** @readonly */
97
+ size,
40
98
 
41
- /**
42
- * @readonly
43
- * @type {<T>(_: (_: T) => boolean) => (_: Iterable<T>) => T|undefined}
44
- */
45
- find: f => c => {
46
- for (const i of c) {
47
- if (f(i)) {
48
- return i
49
- }
50
- }
51
- return undefined
52
- }
99
+ /** @readonly */
100
+ entries,
101
+
102
+ /** @readonly */
103
+ map,
104
+
105
+ /** @readonly */
106
+ exclusiveScan,
107
+
108
+ /** @readonly */
109
+ inclusiveScan,
110
+
111
+ /** @readonly */
112
+ find,
53
113
  }
package/iterable/test.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const i = require('.')
2
- const { pipe } = require('../func')
2
+ const { pipe } = require('../function')
3
3
 
4
4
  {
5
5
  const r = i.sum([120, 300, 42])
@@ -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
  }
@@ -1,9 +1,8 @@
1
1
  const array = require('../array')
2
- const { pipe } = require('../func')
2
+ const { pipe } = require('../function')
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('../sequence').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.162",
3
+ "version": "0.0.167",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -1,4 +1,4 @@
1
- const { pipe, id } = require('../func')
1
+ const { pipe, id } = require('../function')
2
2
 
3
3
  /**
4
4
  * @template S
@@ -38,6 +38,45 @@ 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
+ * @template R
63
+ * @template I
64
+ * @typedef {{
65
+ * readonly exlusive: ExlusiveScan<T, R>
66
+ * readonly default: I
67
+ * }} InclusiveScan
68
+ */
69
+
70
+ /**
71
+ * @template T
72
+ * @typedef {readonly[number, T]} Entry
73
+ */
74
+
75
+ /** @type {(index: number) => <T>(value: T) => readonly[Entry<T>, ExlusiveScan<T, Entry<T>>]} */
76
+ const entriesFrom = index => value => [[index, value], entriesFrom(index + 1)]
77
+
78
+ const entries = entriesFrom(0)
79
+
41
80
  module.exports = {
42
81
  /** @readonly */
43
82
  map,
@@ -45,4 +84,8 @@ module.exports = {
45
84
  join,
46
85
  /** @readonly */
47
86
  sum,
87
+ /** @readonly */
88
+ size,
89
+ /** @readonly */
90
+ entries,
48
91
  }
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
 
package/func/index.js DELETED
@@ -1,12 +0,0 @@
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
- }