functionalscript 0.0.306 → 0.0.307

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.
@@ -21,18 +21,18 @@ const split = path => path.split('/')
21
21
  /** @typedef {readonly[list.List<string>] | undefined} OptionList */
22
22
 
23
23
  /** @type {(s: OptionList) => (items: string) => OptionList} */
24
- const normItemsOp = prior => item => {
24
+ const normItemsOp = prior => first => {
25
25
  if (prior === undefined) { return undefined }
26
- const priorList = prior[0]
27
- switch (item) {
26
+ const tail = prior[0]
27
+ switch (first) {
28
28
  case '': case '.': { return prior }
29
29
  case '..': {
30
- const result = list.next(priorList)
30
+ const result = list.next(tail)
31
31
  if (result === undefined) { return undefined }
32
32
  return [result.tail]
33
33
  }
34
34
  default: {
35
- return [list.nonEmpty(item)(priorList)]
35
+ return [{ first, tail }]
36
36
  }
37
37
  }
38
38
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.306",
3
+ "version": "0.0.307",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -44,14 +44,13 @@ const { logicalNot, strictEqual, stateScanToScan, reduceToScan, foldToScan } = r
44
44
  * }} Concat
45
45
  */
46
46
 
47
- /** @type {<T>(first: T) => (tail: List<T>) => NonEmpty<T>} */
48
- const nonEmpty = first => tail => ({ first, tail })
49
-
50
- /** @type {(i: number) => <T>(array: readonly T[]) => Result<T>} */
51
- const fromArrayAt = i => array => i < array.length ? nonEmpty(array[i])(() => fromArrayAt(i + 1)(array)) : undefined
52
-
53
47
  /** @type {<T>(array: readonly T[]) => Result<T>} */
54
- const fromArray = fromArrayAt(0)
48
+ const fromArray = array => {
49
+ /** @typedef {typeof array extends readonly (infer T)[] ? T : never} T */
50
+ /** @type {(i: number) => Result<T>} */
51
+ const at = i => i < array.length ? { first: array[i], tail: () => at(i + 1) } : undefined
52
+ return at(0)
53
+ }
55
54
 
56
55
  /** @type {<T>(a: List<T>) => (b: List<T>) => List<T>} */
57
56
  const concat = a => b => b === undefined ? a : ({ isConcat: true, a, b })
@@ -78,7 +77,7 @@ const next = list => {
78
77
  }
79
78
 
80
79
  if (a !== undefined) {
81
- return nonEmpty(a.first)(concat(a.tail)(b))
80
+ return { first: a.first, tail: concat(a.tail)(b) }
82
81
  }
83
82
 
84
83
  if (b === undefined) { return undefined }
@@ -120,7 +119,7 @@ const flatStep = n => concat(n.first)(flat(n.tail))
120
119
  const flat = apply(flatStep)
121
120
 
122
121
  /** @type {<I, O>(f: (value: I) => O) => (n: NonEmpty<I>) => List<O>} */
123
- const mapStep = f => n => nonEmpty(f(n.first))(map(f)(n.tail))
122
+ const mapStep = f => n => ({ first: f(n.first), tail: map(f)(n.tail) })
124
123
 
125
124
  /** @type {<I, O>(f: (value: I) => O) => (input: List<I>) => List<O>} */
126
125
  const map = f => apply(mapStep(f))
@@ -131,7 +130,7 @@ const flatMap = f => compose(map(f))(flat)
131
130
  /** @type {<T>(f: (value: T) => boolean) => (n: NonEmpty<T>) => List<T>} */
132
131
  const filterStep = f => n => {
133
132
  const tail = filter(f)(n.tail)
134
- return f(n.first) ? nonEmpty(n.first)(tail) : tail
133
+ return f(n.first) ? { first: n.first, tail } : tail
135
134
  }
136
135
 
137
136
  /** @type {<T>(f: (value: T) => boolean) => (input: List<T>) => List<T>} */
@@ -140,20 +139,20 @@ const filter = f => apply(filterStep(f))
140
139
  /** @type {<I, O>(f: (value: I) => O|undefined) => (n: NonEmpty<I>) => List<O>} */
141
140
  const filterMapStep = f => n => {
142
141
  const [first, tail] = [f(n.first), filterMap(f)(n.tail)]
143
- return first === undefined ? tail : nonEmpty(first)(tail)
142
+ return first === undefined ? tail : { first, tail }
144
143
  }
145
144
 
146
145
  /** @type {<I, O>(f: (value: I) => O|undefined) => (input: List<I>) => List<O>} */
147
146
  const filterMap = f => apply(filterMapStep(f))
148
147
 
149
148
  /** @type {<T>(f: (value: T) => boolean) => (n: NonEmpty<T>) => List<T>} */
150
- const takeWhileStep = f => n => f(n.first) ? nonEmpty(n.first)(takeWhile(f)(n.tail)) : undefined
149
+ const takeWhileStep = f => n => f(n.first) ? { first: n.first, tail: takeWhile(f)(n.tail) } : undefined
151
150
 
152
151
  /** @type {<T>(f: (value: T) => boolean) => (input: List<T>) => List<T>} */
153
152
  const takeWhile = f => apply(takeWhileStep(f))
154
153
 
155
154
  /** @type {(n: number) => <T>(result: NonEmpty<T>) => List<T>} */
156
- const takeStep = n => ne => 0 < n ? nonEmpty(ne.first)(take(n - 1)(ne.tail)) : undefined
155
+ const takeStep = n => ne => 0 < n ? { first: ne.first, tail: take(n - 1)(ne.tail) } : undefined
157
156
 
158
157
  /** @type {(n: number) => <T>(input: List<T>) => List<T>} */
159
158
  const take = n => apply(takeStep(n))
@@ -177,10 +176,11 @@ const first = def => input => {
177
176
  return result.first
178
177
  }
179
178
 
180
- /** @type {<D>(def: D) => <T>(input: List<T>) => D|T} */
181
- const last = def => input => {
182
- /** @typedef {typeof input extends List<infer T> ? T : never} T */
183
- let i = nonEmpty(/** @type {(typeof def)|T} */(def))(input)
179
+ /** @type {<D>(first: D) => <T>(tail: List<T>) => D|T} */
180
+ const last = first => tail => {
181
+ /** @typedef {typeof tail extends List<infer T> ? T : never} T */
182
+ /** @type {NonEmpty<typeof first|T>} */
183
+ let i = { first, tail }
184
184
  while (true) {
185
185
  const result = next(i.tail)
186
186
  if (result === undefined) {
@@ -212,19 +212,19 @@ const includes = value => input => some(map(strictEqual(value))(input))
212
212
  const countdown = count => () => {
213
213
  if (count <= 0) { return undefined }
214
214
  const first = count - 1
215
- return nonEmpty(first)(countdown(first))
215
+ return { first, tail: countdown(first) }
216
216
  }
217
217
 
218
218
  /** @type {<T>(list: List<T>) => List<T>} */
219
219
  const cycle = list => () => {
220
220
  const i = next(list)
221
- return i === undefined ? undefined : nonEmpty(i.first)(concat(i.tail)(cycle(list)))
221
+ return i === undefined ? undefined : { first: i.first, tail: concat(i.tail)(cycle(list)) }
222
222
  }
223
223
 
224
224
  /** @type {<I, O>(op: operator.Scan<I, O>) => (ne: NonEmpty<I>) => List<O>} */
225
225
  const scanStep = op => ne => {
226
- const [o, newOp] = op(ne.first)
227
- return nonEmpty(o)(scan(newOp)(ne.tail))
226
+ const [first, newOp] = op(ne.first)
227
+ return { first, tail: scan(newOp)(ne.tail) }
228
228
  }
229
229
 
230
230
  /** @type {<I, O>(op: operator.Scan<I, O>) => (input: List<I>) => List<O>} */
@@ -263,13 +263,13 @@ const length = reduce(operator.counter)(0)
263
263
  const entryOperator = index => value => [[index, value], index + 1]
264
264
 
265
265
  /** @type {<T>(input: List<T>) => List<Entry<T>>} */
266
- const entries = (input) => {
266
+ const entries = input => {
267
267
  /** @typedef {typeof input extends List<infer T> ? T : never} T */
268
268
  return stateScan(/** @type {operator.StateScan<T, Number, Entry<T>>} */(entryOperator))(0)(input)
269
269
  }
270
270
 
271
271
  /** @type {<T>(prior: List<T>) => (value: T) => List<T>} */
272
- const reverseOperator = prior => value => nonEmpty(value)(prior)
272
+ const reverseOperator = tail => first => ({ first, tail })
273
273
 
274
274
  /** @type {<T>(input: List<T>) => List<T>} */
275
275
  const reverse = reduce(reverseOperator)(undefined)
@@ -283,15 +283,15 @@ const zip = a => b => () => {
283
283
  if (aResult === undefined) { return undefined }
284
284
  const bResult = next(b)
285
285
  if (bResult === undefined) { return undefined }
286
- return nonEmpty(tuple2(aResult.first)(bResult.first))(zip(aResult.tail)(bResult.tail))
286
+ return { first: tuple2(aResult.first)(bResult.first), tail: zip(aResult.tail)(bResult.tail) }
287
287
  }
288
288
 
289
289
  /** @type {<T>(e: operator.Equal<T>) => (a: List<T>) => (b: List<T>) => List<boolean>} */
290
290
  const equalZip = e => a => b => () => {
291
291
  const [aResult, bResult] = [next(a), next(b)]
292
292
  return aResult === undefined || bResult === undefined
293
- ? nonEmpty(aResult === bResult)(undefined)
294
- : nonEmpty(e(aResult.first)(bResult.first))(equalZip(e)(aResult.tail)(bResult.tail))
293
+ ? { first: aResult === bResult, tail: undefined }
294
+ : { first: e(aResult.first)(bResult.first), tail: equalZip(e)(aResult.tail)(bResult.tail) }
295
295
  }
296
296
 
297
297
  /** @type {<T>(e: operator.Equal<T>) => (a: List<T>) => (b: List<T>) => boolean} */
@@ -299,24 +299,20 @@ const equal = e => a => b => every(equalZip(e)(a)(b))
299
299
 
300
300
  /** @type {(s: string) => List<number>} */
301
301
  const toCharCodes = s => {
302
- /** @type {(i: number) => List<number>} */
303
- const at = i => () => {
304
- const r = s.charCodeAt(i)
305
- if (isNaN(r)) { return undefined }
306
- return { first: r, tail: at(i + 1) }
302
+ /** @type {(i: number) => Result<number>} */
303
+ const at = i => {
304
+ const first = s.charCodeAt(i)
305
+ return isNaN(first) ? undefined : { first, tail: () => at(i + 1) }
307
306
  }
308
307
  return at(0)
309
308
  }
310
309
 
311
- /** @type {(x: List<number>) => string} */
312
- const fromCharCodes = x => fold(operator.concat)('')(map(String.fromCharCode)(x))
310
+ const fromCharCodes = compose(map(String.fromCharCode))(fold(operator.concat)(''))
313
311
 
314
312
  module.exports = {
315
313
  /** @readonly */
316
314
  empty: undefined,
317
315
  /** @readonly */
318
- nonEmpty,
319
- /** @readonly */
320
316
  concat,
321
317
  /** @readonly */
322
318
  next,