functionalscript 0.0.488 → 0.0.489

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/README.md CHANGED
@@ -3,8 +3,10 @@
3
3
  FunctionalScript is a purely functional programming language and a strict subset of
4
4
  [ECMAScript](https://en.wikipedia.org/wiki/ECMAScript)/[JavaScript](https://en.wikipedia.org/wiki/JavaScript). It's inspired by
5
5
 
6
- - [JSON](https://en.wikipedia.org/wiki/JSON) as a subset of JavaScript. JSON is also a subset of FunctionalScript.
7
- - [asm.JS](https://en.wikipedia.org/wiki/Asm.js)/[WebAssembly](https://en.wikipedia.org/wiki/WebAssembly), as a subset of JavaScript.
6
+ - [JSON](https://en.wikipedia.org/wiki/JSON) and [JSON5](https://json5.org/) as subsets of JavaScript.
7
+ JSON is also a subset of FunctionalScript.
8
+ - [asm.JS](https://en.wikipedia.org/wiki/Asm.js)/[WebAssembly](https://en.wikipedia.org/wiki/WebAssembly),
9
+ as a subset of JavaScript.
8
10
  - [TypeScript](https://en.wikipedia.org/wiki/TypeScript), as a superset of JavaScript.
9
11
 
10
12
  [A brief description of FunctionalScript Programming Language](./doc/LANGUAGE.md).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.488",
3
+ "version": "0.0.489",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "module.f.cjs",
6
6
  "scripts": {
@@ -85,16 +85,16 @@ const uncheckTail = a => a.slice(1)
85
85
  const uncheckHead = a => a.slice(0, -1)
86
86
 
87
87
  /** @type {(index: number) => <T>(a: readonly T[]) => T|null} */
88
- const unsafeAt = i => a => {
88
+ const at = i => a => {
89
89
  const r = a[i]
90
90
  return r === void 0 ? null : r
91
91
  }
92
92
 
93
93
  /** @type {<T>(_: readonly T[]) => T|null} */
94
- const first = unsafeAt(0)
94
+ const first = at(0)
95
95
 
96
96
  /** @type {<T>(_: readonly T[]) => T|null} */
97
- const last = a => unsafeAt(a.length - 1)(a)
97
+ const last = a => at(a.length - 1)(a)
98
98
 
99
99
  /** @type {<T>(_: readonly T[]) => readonly T[] | null} */
100
100
  const tail = a => a.length === 0 ? null : uncheckTail(a)
@@ -117,9 +117,6 @@ const splitLast = a => {
117
117
  return [uncheckHead(a), lastA]
118
118
  }
119
119
 
120
- /** @type {(index: number) => <T>(a: readonly T[]) => readonly[T]|null} */
121
- const at = index => a => index < a.length ? [a[index]] : null
122
-
123
120
  module.exports = {
124
121
  /** @readonly */
125
122
  at,
@@ -12,8 +12,7 @@ module.exports = {
12
12
  at: [
13
13
  () => {
14
14
  const result = _.at(2)([1, 20, 300])
15
- if (result === null) { throw result }
16
- if (result[0] !== 300) { throw result }
15
+ if (result !== 300) { throw result }
17
16
  },
18
17
 
19
18
  () => {
@@ -1,4 +1,4 @@
1
- const { fn } = require('../function/module.f.cjs')
1
+ const { fn, compose } = require('../function/module.f.cjs')
2
2
  const rangeMap = require('../range_map/module.f.cjs')
3
3
  const sortedSet = require('../sorted_set/module.f.cjs')
4
4
  const list = require('../list/module.f.cjs')
@@ -31,17 +31,17 @@ const union = a => b => a | b
31
31
  /** @type {(a: ByteSet) => (b: ByteSet) => ByteSet} */
32
32
  const intersect = a => b => a & b
33
33
 
34
- /** @type {(a: ByteSet) => (b: ByteSet) => ByteSet} */
35
- const difference = a => b => intersect(a)(complement(b))
36
-
37
34
  /** @type {(n: ByteSet) => ByteSet} */
38
35
  const complement = n => universe ^ n
39
36
 
37
+ /** @type {(a: ByteSet) => (b: ByteSet) => ByteSet} */
38
+ const difference = compose(intersect)(compose(complement))
39
+
40
40
  // additional operations
41
41
 
42
- const set = fn(one).then(union).result
42
+ const set = compose(one)(union)
43
43
 
44
- const setRange = fn(range).then(union).result
44
+ const setRange = compose(range)(union)
45
45
 
46
46
  /** @type {(n: Byte) => (s: ByteSet) => ByteSet} */
47
47
  const unset = n => s => difference(s)(one(n))
@@ -49,8 +49,7 @@ const unset = n => s => difference(s)(one(n))
49
49
  const counter = reverse(countdown(256))
50
50
 
51
51
  /** @type {(n: ByteSet) => (s: string) => (i: number) => rangeMap.RangeMap<sortedSet.SortedSet<string>>} */
52
- const toRangeMapOp = n => s => i =>
53
- {
52
+ const toRangeMapOp = n => s => i => {
54
53
  const current = has(i + 1)(n)
55
54
  const prev = has(i)(n)
56
55
  if (current === prev) { return null }
@@ -1,4 +1,5 @@
1
- const { compose, identity } = require('../function/module.f.cjs')
1
+ const function_ = require('../function/module.f.cjs')
2
+ const { identity, fn, compose } = function_
2
3
  const operator = require('../function/operator/module.f.cjs')
3
4
  const {
4
5
  counter,
@@ -121,13 +122,13 @@ const apply = f => input => () => {
121
122
  }
122
123
 
123
124
  /** @type {<T>(n: NonEmpty<List<T>>) => List<T>} */
124
- const flatStep = n => concat(n.first)(flat(n.tail))
125
+ const flatStep = ({ first, tail }) => concat(first)(flat(tail))
125
126
 
126
127
  /** @type {<T>(list: List<List<T>>) => Thunk<T>} */
127
128
  const flat = apply(flatStep)
128
129
 
129
130
  /** @type {<I, O>(f: (value: I) => O) => (n: NonEmpty<I>) => List<O>} */
130
- const mapStep = f => n => ({ first: f(n.first), tail: map(f)(n.tail) })
131
+ const mapStep = f => ({ first, tail }) => ({ first: f(first), tail: map(f)(tail) })
131
132
 
132
133
  /** @type {<I, O>(f: (value: I) => O) => (input: List<I>) => Thunk<O>} */
133
134
  const map = f => apply(mapStep(f))
@@ -136,9 +137,9 @@ const map = f => apply(mapStep(f))
136
137
  const flatMap = f => compose(map(f))(flat)
137
138
 
138
139
  /** @type {<T>(f: (value: T) => boolean) => (n: NonEmpty<T>) => List<T>} */
139
- const filterStep = f => n => {
140
- const tail = filter(f)(n.tail)
141
- return f(n.first) ? { first: n.first, tail } : tail
140
+ const filterStep = f => ({ first, tail }) => {
141
+ const newTail = filter(f)(tail)
142
+ return f(first) ? { first, tail: newTail } : newTail
142
143
  }
143
144
 
144
145
  /** @type {<T>(f: (value: T) => boolean) => (input: List<T>) => Thunk<T>} */
@@ -154,13 +155,13 @@ const filterMapStep = f => n => {
154
155
  const filterMap = f => apply(filterMapStep(f))
155
156
 
156
157
  /** @type {<T>(f: (value: T) => boolean) => (n: NonEmpty<T>) => List<T>} */
157
- const takeWhileStep = f => n => f(n.first) ? { first: n.first, tail: takeWhile(f)(n.tail) } : null
158
+ const takeWhileStep = f => ({ first, tail }) => f(first) ? { first, tail: takeWhile(f)(tail) } : null
158
159
 
159
160
  /** @type {<T>(f: (value: T) => boolean) => (input: List<T>) => Thunk<T>} */
160
161
  const takeWhile = f => apply(takeWhileStep(f))
161
162
 
162
163
  /** @type {(n: number) => <T>(result: NonEmpty<T>) => List<T>} */
163
- const takeStep = n => ne => 0 < n ? { first: ne.first, tail: take(n - 1)(ne.tail) } : null
164
+ const takeStep = n => ({ first, tail }) => 0 < n ? { first: first, tail: take(n - 1)(tail) } : null
164
165
 
165
166
  /** @type {(n: number) => <T>(input: List<T>) => Thunk<T>} */
166
167
  const take = n => apply(takeStep(n))
@@ -179,8 +180,8 @@ const drop = n => apply(dropStep(n))
179
180
 
180
181
  /** @type {<D>(def: D) => <T>(input: List<T>) => D|T} */
181
182
  const first = def => input => {
182
- const result = next(input)
183
- return result === null ? def : result.first
183
+ const ne = next(input)
184
+ return ne === null ? def : ne.first
184
185
  }
185
186
 
186
187
  /** @type {<D>(first: D) => <T>(tail: List<T>) => D|T} */
@@ -198,28 +199,24 @@ const last = first => tail => {
198
199
  }
199
200
 
200
201
  /** @type {<D>(def: D) => <T>(f: (value: T) => boolean) => (input: List<T>) => D|T} */
201
- const find = def => f => input => first(def)(filter(f)(input))
202
-
203
- const findTrue = find(false)
202
+ const find = def => f => compose(filter(f))(first(def))
204
203
 
205
204
  /** @type {(input: List<boolean>) => boolean} */
206
- const some = input => findTrue
207
- (/** @type {(_: boolean) => boolean} */(identity))
208
- (input)
209
-
210
- /** @type {<T>(f: List<T>) => Thunk<boolean>} */
211
- const mapTrue = map(() => true)
205
+ const some = find(false)(identity)
212
206
 
213
207
  /** @type {<T>(input: List<T>) => boolean} */
214
- const isEmpty = input => !some(mapTrue(input))
208
+ const isEmpty = fn(map(() => true))
209
+ .then(some)
210
+ .then(logicalNot)
211
+ .result
215
212
 
216
- const mapNot = map(logicalNot)
217
-
218
- /** @type {(input: List<boolean>) => boolean} */
219
- const every = input => !some(mapNot(input))
213
+ const every = fn(map(logicalNot))
214
+ .then(some)
215
+ .then(logicalNot)
216
+ .result
220
217
 
221
218
  /** @type {<T>(value: T) => (sequence: List<T>) => boolean} */
222
- const includes = value => input => some(map(strictEqual(value))(input))
219
+ const includes = value => compose(map(strictEqual(value)))(some)
223
220
 
224
221
  /** @type {(count: number) => Thunk<number>} */
225
222
  const countdown = count => () => {
@@ -229,7 +226,7 @@ const countdown = count => () => {
229
226
  }
230
227
 
231
228
  /** @type {<T>(v: T) => (c: number) => Thunk<T>} */
232
- const repeat = v => n => map(() => v)(countdown(n))
229
+ const repeat = v => compose(countdown)(map(() => v))
233
230
 
234
231
  /** @type {<T>(list: List<T>) => List<T>} */
235
232
  const cycle = list => () => {
@@ -247,17 +244,16 @@ const scanStep = op => ne => {
247
244
  const scan = op => apply(scanStep(op))
248
245
 
249
246
  /** @type {<I, S, O>(op: operator.StateScan<I, S, O>) => (init: S) => (input: List<I>) => Thunk<O>} */
250
- const stateScan = op => init => scan(stateScanToScan(op)(init))
247
+ const stateScan = op => compose(stateScanToScan(op))(scan)
251
248
 
252
249
  /** @type {<I,O>(op: operator.Fold<I, O>) => (init: O) => (input: List<I>) => Thunk<O>} */
253
- const foldScan = op => init => scan(foldToScan(op)(init))
250
+ const foldScan = op => compose(foldToScan(op))(scan)
254
251
 
255
252
  /** @type {<I,O>(op: operator.Fold<I, O>) => (init: O) => (input: List<I>) => O} */
256
- const fold = op => init => input => last(init)(foldScan(op)(init)(input))
253
+ const fold = op => init => compose(foldScan(op)(init))(last(init))
257
254
 
258
255
  /** @type {<T>(op: operator.Reduce<T>) => <D>(def: D) => (input: List<T>) => D|T} */
259
- const reduce = op => def => input => last(def)(scan(reduceToScan(op))(input))
260
-
256
+ const reduce = op => def => compose(scan(reduceToScan(op)))(last(def))
261
257
 
262
258
  /** @type {<T>(input: List<T>) => number} */
263
259
  const length = fold(counter)(0)
@@ -39,7 +39,8 @@ const at = name => map => {
39
39
  }
40
40
 
41
41
  /** @type {<T>(reduce: operator.Reduce<T>) => (entry: Entry<T>) => (map: Map<T>) => Map<T>} */
42
- const setReduceEntry = reduce => entry => set(keyCmp(entry[0]))(old => old === null ? entry : [old[0], reduce(old[1])(entry[1])])
42
+ const setReduceEntry = reduce => entry =>
43
+ set(keyCmp(entry[0]))(old => old === null ? entry : [old[0], reduce(old[1])(entry[1])])
43
44
 
44
45
  /** @type {<T>(reduce: operator.Reduce<T>) => (name: string) => (value: T) => (map: Map<T>) => Map<T>} */
45
46
  const setReduce = reduce => name => value => setReduceEntry(reduce)([name, value])
@@ -4,6 +4,6 @@ module.exports = () => {
4
4
  const optionSq = _.map(v => v * v)
5
5
  const sq3 = optionSq(3)
6
6
  if (sq3 !== 9) { throw sq3 }
7
- const sqUndefined = optionSq(null)
8
- if (sqUndefined !== null) { throw sqUndefined }
7
+ const sqNull = optionSq(null)
8
+ if (sqNull !== null) { throw sqNull }
9
9
  }
@@ -41,9 +41,8 @@ const { identity } = require('../function/module.f.cjs')
41
41
  */
42
42
 
43
43
  /** @type {<T,S>(reduce: MergeReduce<T,S>) => (state: S) => (a: list.List<T>) => (b: list.List<T>) => list.List<T>} */
44
- const genericMerge = reduce => {
45
- const { reduceOp, tailReduce } = reduce
46
- /** @typedef {typeof reduce extends MergeReduce<infer T, infer S> ? [T, S] : never} TS */
44
+ const genericMerge = ({ reduceOp, tailReduce }) => {
45
+ /** @typedef {typeof reduceOp extends ReduceOp<infer T, infer S> ? [T, S] : never} TS */
47
46
  /** @typedef {TS[0]} T */
48
47
  /** @typedef {TS[1]} S */
49
48
  /** @type {(state: S) => (a: list.List<T>) => (b: list.List<T>) => list.List<T>} */
@@ -21,8 +21,10 @@ const union = cmp => a => b => toArray(merge(cmp)(a)(b))
21
21
  /** @type {<T>(cmp: Cmp<T>) => (a: SortedSet<T>) => (b: SortedSet<T>) => SortedSet<T>} */
22
22
  const intersect = cmp => a => b => toArray(intersectMerge(cmp)(a)(b))
23
23
 
24
+ const tailReduce = () => () => null
25
+
24
26
  /** @type {<T>(cmp: Cmp<T>) => (a: sortedList.SortedList<T>) => (b: sortedList.SortedList<T>) => sortedList.SortedList<T>} */
25
- const intersectMerge = cmp => genericMerge({ reduceOp: intersectReduce(cmp), tailReduce: intersectTail })(null)
27
+ const intersectMerge = cmp => genericMerge({ reduceOp: intersectReduce(cmp), tailReduce })(null)
26
28
 
27
29
  /** @type {<T,S>(cmp: Cmp<T>) => sortedList.ReduceOp<T,S>} */
28
30
  const intersectReduce = cmp => state => a => b => {
@@ -30,8 +32,6 @@ const intersectReduce = cmp => state => a => b => {
30
32
  return [sign === 0 ? a : null, sign, state]
31
33
  }
32
34
 
33
- const intersectTail = () => () => null
34
-
35
35
  /** @type {<T>(cmp: Cmp<T>) => (value: T) => (set: SortedSet<T>) => boolean} */
36
36
  const has = cmp => value => set => find(cmp)(value)(set) === value
37
37