functionalscript 0.0.0 → 0.0.126

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/lib/index.js CHANGED
@@ -1,163 +1,163 @@
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
- * @typedef {{
34
- * get: (_: string) => T|undefined
35
- * set: (_: string) => (_: T) => Dictionary<T>
36
- * entries: () => Iterable<[string, T]>
37
- * }} Dictionary
38
- */
39
-
40
- /**
41
- * @template T
42
- * @typedef {{
43
- * [_ in string]: T
44
- * }} InternalMap
45
- */
46
-
47
- const emptyDictionary = {
48
- get: () => undefined,
49
- /** @type {(_: string) => <T>(_: T) => Dictionary<T>} */
50
- set: key => value => dictionary({[key]: value}),
51
- entries: () => []
52
- }
53
-
54
- /** @type {<T>(_: InternalMap<T>) => Dictionary<T>} */
55
- const dictionary = internal => ({
56
- get: key => internal[key],
57
- set: key => value => dictionary({ ...internal, [key]: value }),
58
- entries: () => Object.entries(internal),
59
- })
60
-
61
- /** @type {<A>(_: A) => <B>(_: B) => [A, B]} */
62
- const tuple2 = a => b => [a, b]
63
-
64
- /** @type {<T>(_: (_: string) => T) => (_: Dictionary<T>) => (_: string) => [T, Dictionary<T>]} */
65
- const cache = f => d => k => {
66
- const set = () => {
67
- const r = f(k)
68
- return tuple2(r)(d.set(k)(r))
69
- }
70
- const result = d.get(k)
71
- return result !== undefined ? [result, d] : set()
72
- }
73
-
74
- /**
75
- * @template T
76
- * @template R
77
- * @typedef {{
78
- * merge: (_: R) => (_: T) => R
79
- * init: R
80
- * }} Reduce
81
- */
82
-
83
- /** @type {<I, X>(_: (_: I) => X) => <O>(_: (_: X) => O) => (_: I) => O} */
84
- const pipe = g => f => x => f(g(x))
85
-
86
- /** @type {<T, R>(_: (_: T) => R) => (_: T|undefined) => R|undefined} */
87
- const optionMap = f => x => x === undefined ? undefined : f(x)
88
-
89
- /** @type {<T>(_: T[]) => T[]} */
90
- const uncheckTail = a => a.slice(1)
91
-
92
- /** @type {<T>(_: T[]) => T[]} */
93
- const uncheckHead = a => a.slice(0, -1)
94
-
95
- /** @type {<T>(_: T[]) => T|undefined} */
96
- const last = a => a[a.length - 1]
97
-
98
- module.exports = {
99
-
100
- panic,
101
-
102
- todo: () => panic('not implemented'),
103
-
104
- /** @type {(_: string) => (_: boolean) => void} */
105
- panic_if: message => condition => condition ? panic(message) : undefined,
106
-
107
- // /** @type {<T>() => Dictionary<T>} */
108
- // dictionary: () => dictionary({}),
109
-
110
- emptyDictionary,
111
-
112
- /** @type {<T>(_: Continuation<T>) => T} */
113
- trampoline: continuation => {
114
- while (true) {
115
- if (typeof continuation !== 'function') {
116
- return continuation[0]
117
- }
118
- continuation = continuation()
119
- }
120
- },
121
-
122
- /** @type {(s: string) => Reduce<string, string>} */
123
- join: s => ({ merge: a => i => a === '' ? i : a + s + i, init: ''}),
124
-
125
- pipe,
126
-
127
- /** @type {Reduce<number, number>} */
128
- sum: { merge: a => i => a + i, init: 0 },
129
-
130
- /** @type {<I, X>(_: (_: I) => X) => <O>(_: Reduce<X, O>) => Reduce<I, O>} */
131
- map: f => ({merge, init}) => ({
132
- merge: pipe(merge)(pipe(f)),
133
- init,
134
- }),
135
-
136
- last,
137
-
138
- optionMap,
139
-
140
- cache,
141
-
142
- /** @type {<T>(_: T[]) => T[]|undefined} */
143
- tail: a => a.length === 0 ? undefined : uncheckTail(a),
144
-
145
- /** @type {<T>(_: T[]) => [T, T[]]|undefined} */
146
- splitFirst: a => {
147
- /** @typedef {typeof a[0]} T*/
148
- /** @type {(_: T) => [T, T[]]} */
149
- const split = first => [first, uncheckTail(a)]
150
- return optionMap(split)(a[0])
151
- },
152
-
153
- /** @type {<T>(_: T[]) => T[]|undefined} */
154
- head: a => a.length === 0 ? undefined : uncheckHead(a),
155
-
156
- /** @type {<T>(_: T[]) => [T[], T]|undefined} */
157
- splitLast: a => {
158
- /** @typedef {typeof a[0]} T*/
159
- /** @type {(_: T) => [T[], T]} */
160
- const split = x => [uncheckHead(a), x]
161
- return optionMap(split)(last(a))
162
- },
163
- }
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
+ * @typedef {{
34
+ * get: (_: string) => T|undefined
35
+ * set: (_: string) => (_: T) => Dictionary<T>
36
+ * entries: () => Iterable<[string, T]>
37
+ * }} Dictionary
38
+ */
39
+
40
+ /**
41
+ * @template T
42
+ * @typedef {{
43
+ * [_ in string]: T
44
+ * }} InternalMap
45
+ */
46
+
47
+ const emptyDictionary = {
48
+ get: () => undefined,
49
+ /** @type {(_: string) => <T>(_: T) => Dictionary<T>} */
50
+ set: key => value => dictionary({[key]: value}),
51
+ entries: () => []
52
+ }
53
+
54
+ /** @type {<T>(_: InternalMap<T>) => Dictionary<T>} */
55
+ const dictionary = internal => ({
56
+ get: key => internal[key],
57
+ set: key => value => dictionary({ ...internal, [key]: value }),
58
+ entries: () => Object.entries(internal),
59
+ })
60
+
61
+ /** @type {<A>(_: A) => <B>(_: B) => [A, B]} */
62
+ const tuple2 = a => b => [a, b]
63
+
64
+ /** @type {<T>(_: (_: string) => T) => (_: Dictionary<T>) => (_: string) => [T, Dictionary<T>]} */
65
+ const cache = f => d => k => {
66
+ const set = () => {
67
+ const r = f(k)
68
+ return tuple2(r)(d.set(k)(r))
69
+ }
70
+ const result = d.get(k)
71
+ return result !== undefined ? [result, d] : set()
72
+ }
73
+
74
+ /**
75
+ * @template T
76
+ * @template R
77
+ * @typedef {{
78
+ * merge: (_: R) => (_: T) => R
79
+ * init: R
80
+ * }} Reduce
81
+ */
82
+
83
+ /** @type {<I, X>(_: (_: I) => X) => <O>(_: (_: X) => O) => (_: I) => O} */
84
+ const pipe = g => f => x => f(g(x))
85
+
86
+ /** @type {<T, R>(_: (_: T) => R) => (_: T|undefined) => R|undefined} */
87
+ const optionMap = f => x => x === undefined ? undefined : f(x)
88
+
89
+ /** @type {<T>(_: T[]) => T[]} */
90
+ const uncheckTail = a => a.slice(1)
91
+
92
+ /** @type {<T>(_: T[]) => T[]} */
93
+ const uncheckHead = a => a.slice(0, -1)
94
+
95
+ /** @type {<T>(_: T[]) => T|undefined} */
96
+ const last = a => a[a.length - 1]
97
+
98
+ module.exports = {
99
+
100
+ panic,
101
+
102
+ todo: () => panic('not implemented'),
103
+
104
+ /** @type {(_: string) => (_: boolean) => void} */
105
+ panic_if: message => condition => condition ? panic(message) : undefined,
106
+
107
+ // /** @type {<T>() => Dictionary<T>} */
108
+ // dictionary: () => dictionary({}),
109
+
110
+ emptyDictionary,
111
+
112
+ /** @type {<T>(_: Continuation<T>) => T} */
113
+ trampoline: continuation => {
114
+ while (true) {
115
+ if (typeof continuation !== 'function') {
116
+ return continuation[0]
117
+ }
118
+ continuation = continuation()
119
+ }
120
+ },
121
+
122
+ /** @type {(s: string) => Reduce<string, string>} */
123
+ join: s => ({ merge: a => i => a === '' ? i : a + s + i, init: ''}),
124
+
125
+ pipe,
126
+
127
+ /** @type {Reduce<number, number>} */
128
+ sum: { merge: a => i => a + i, init: 0 },
129
+
130
+ /** @type {<I, X>(_: (_: I) => X) => <O>(_: Reduce<X, O>) => Reduce<I, O>} */
131
+ map: f => ({merge, init}) => ({
132
+ merge: pipe(merge)(pipe(f)),
133
+ init,
134
+ }),
135
+
136
+ last,
137
+
138
+ optionMap,
139
+
140
+ cache,
141
+
142
+ /** @type {<T>(_: T[]) => T[]|undefined} */
143
+ tail: a => a.length === 0 ? undefined : uncheckTail(a),
144
+
145
+ /** @type {<T>(_: T[]) => [T, T[]]|undefined} */
146
+ splitFirst: a => {
147
+ /** @typedef {typeof a[0]} T*/
148
+ /** @type {(_: T) => [T, T[]]} */
149
+ const split = first => [first, uncheckTail(a)]
150
+ return optionMap(split)(a[0])
151
+ },
152
+
153
+ /** @type {<T>(_: T[]) => T[]|undefined} */
154
+ head: a => a.length === 0 ? undefined : uncheckHead(a),
155
+
156
+ /** @type {<T>(_: T[]) => [T[], T]|undefined} */
157
+ splitLast: a => {
158
+ /** @typedef {typeof a[0]} T*/
159
+ /** @type {(_: T) => [T[], T]} */
160
+ const split = x => [uncheckHead(a), x]
161
+ return optionMap(split)(last(a))
162
+ },
163
+ }
@@ -1,33 +1,33 @@
1
- const lib = require('../')
2
-
3
- /** @type {<T, R>(_: lib.Reduce<T, R>) => (_: Iterable<T>) => R} */
4
- const reduce = ({merge, init}) => c => {
5
- let result = init
6
- for (let i of c) {
7
- result = merge(result)(i)
8
- }
9
- return result
10
- }
11
-
12
- module.exports = {
13
- reduce,
14
- join: lib.pipe(lib.join)(reduce),
15
- sum: reduce(lib.sum),
16
- /** @type {<T, R>(_: (_: T) => R) => (_: Iterable<T>) => Iterable<R>} */
17
- map: f => c => ({
18
- *[Symbol.iterator]() {
19
- for (let i of c) {
20
- yield f(i)
21
- }
22
- }
23
- }),
24
- /** @type {<T>(_: (_: T) => boolean) => (_: Iterable<T>) => T|undefined} */
25
- find: f => c => {
26
- for (let i of c) {
27
- if (f(i)) {
28
- return i
29
- }
30
- }
31
- return undefined
32
- }
33
- }
1
+ const lib = require('../')
2
+
3
+ /** @type {<T, R>(_: lib.Reduce<T, R>) => (_: Iterable<T>) => R} */
4
+ const reduce = ({merge, init}) => c => {
5
+ let result = init
6
+ for (let i of c) {
7
+ result = merge(result)(i)
8
+ }
9
+ return result
10
+ }
11
+
12
+ module.exports = {
13
+ reduce,
14
+ join: lib.pipe(lib.join)(reduce),
15
+ sum: reduce(lib.sum),
16
+ /** @type {<T, R>(_: (_: T) => R) => (_: Iterable<T>) => Iterable<R>} */
17
+ map: f => c => ({
18
+ *[Symbol.iterator]() {
19
+ for (let i of c) {
20
+ yield f(i)
21
+ }
22
+ }
23
+ }),
24
+ /** @type {<T>(_: (_: T) => boolean) => (_: Iterable<T>) => T|undefined} */
25
+ find: f => c => {
26
+ for (let i of c) {
27
+ if (f(i)) {
28
+ return i
29
+ }
30
+ }
31
+ return undefined
32
+ }
33
+ }
@@ -1,41 +1,41 @@
1
- const i = require('.')
2
- const lib = require('..')
3
-
4
- {
5
- const r = i.sum([120, 300, 42])
6
- lib.panic_if('reduce')(r !== 462)
7
- }
8
-
9
- {
10
- lib.panic_if('first sum')(i.sum([1, 2]) !== 3)
11
- lib.panic_if('second sum')(i.sum([1, 2]) !== 3)
12
- }
13
-
14
- {
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)
20
- }
21
-
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')
26
- }
27
-
28
- {
29
- lib.panic_if('find')(i.find(x => x === 'c')(['a', 'b', 'c']) !== 'c')
30
- }
31
-
32
- {
33
- /** @type {(_: string) => string|undefined} */
34
- const file = _ => 'x'
35
- /** @type {(_: string) => string|undefined} */
36
- const x = p => lib.pipe
37
- (i.map(x => file(x())))
38
- (i.find(x => x !== undefined))
39
- ([() => p, () => `${p}.js`, () => `${p}/index.js`])
40
- lib.panic_if('map.find')(x('index.js') !== 'x')
1
+ const i = require('.')
2
+ const lib = require('..')
3
+
4
+ {
5
+ const r = i.sum([120, 300, 42])
6
+ lib.panic_if('reduce')(r !== 462)
7
+ }
8
+
9
+ {
10
+ lib.panic_if('first sum')(i.sum([1, 2]) !== 3)
11
+ lib.panic_if('second sum')(i.sum([1, 2]) !== 3)
12
+ }
13
+
14
+ {
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)
20
+ }
21
+
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')
26
+ }
27
+
28
+ {
29
+ lib.panic_if('find')(i.find(x => x === 'c')(['a', 'b', 'c']) !== 'c')
30
+ }
31
+
32
+ {
33
+ /** @type {(_: string) => string|undefined} */
34
+ const file = _ => 'x'
35
+ /** @type {(_: string) => string|undefined} */
36
+ const x = p => lib.pipe
37
+ (i.map(x => file(x())))
38
+ (i.find(x => x !== undefined))
39
+ ([() => p, () => `${p}.js`, () => `${p}/index.js`])
40
+ lib.panic_if('map.find')(x('index.js') !== 'x')
41
41
  }
package/lib/test.js CHANGED
@@ -1,12 +1,12 @@
1
- const lib = require('./index')
2
-
3
- require('./iterable/test')
4
-
5
- {
6
- const map = lib.emptyDictionary.set('x')(12).set('y')(44)
7
- lib.panic_if('map.get(\'x\')')(map.get('x') !== 12)
8
- lib.panic_if('map.get(\'y\')')(map.get('y') !== 44)
9
- lib.panic_if('map.get(\'a\')')(map.get('a') !== undefined)
10
- const entries = Array.from(map.entries())
11
- lib.panic_if('map.entries()')(entries.length !== 2)
12
- }
1
+ const lib = require('./index')
2
+
3
+ require('./iterable/test')
4
+
5
+ {
6
+ const map = lib.emptyDictionary.set('x')(12).set('y')(44)
7
+ lib.panic_if('map.get(\'x\')')(map.get('x') !== 12)
8
+ lib.panic_if('map.get(\'y\')')(map.get('y') !== 44)
9
+ lib.panic_if('map.get(\'a\')')(map.get('a') !== undefined)
10
+ const entries = Array.from(map.entries())
11
+ lib.panic_if('map.entries()')(entries.length !== 2)
12
+ }