functionalscript 0.0.220 → 0.0.222

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.220",
3
+ "version": "0.0.222",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/sequence/index.js CHANGED
@@ -24,7 +24,12 @@ const op = require('../function/operator')
24
24
 
25
25
  /**
26
26
  * @template T
27
- * @typedef { undefined | { readonly first: T, readonly tail: Sequence<T> } } Result
27
+ * @typedef { undefined | ResultOne<T> } Result
28
+ */
29
+
30
+ /**
31
+ * @template T
32
+ * @typedef {{ readonly first: T, readonly tail: Sequence<T> }} ResultOne
28
33
  */
29
34
 
30
35
  const empty = () => undefined
@@ -73,15 +78,11 @@ const iterable = sequence => ({
73
78
  let i = sequence
74
79
  while (true) {
75
80
  if (i instanceof Array) { return yield *i }
76
- const n = node(i)
81
+ const n = next(i)
77
82
  if (n === undefined) { return }
78
- if (n instanceof Array) {
79
- i = concatNext(n)
80
- } else {
81
- const { first, tail } = n
82
- yield first
83
- i = tail
84
- }
83
+ const { first, tail } = n
84
+ yield first
85
+ i = tail
85
86
  }
86
87
  }
87
88
  })
@@ -92,47 +93,50 @@ const toArray = sequence => {
92
93
  return Array.from(iterable(sequence))
93
94
  }
94
95
 
95
- /** @type {<T>(sequence: Sequence<Sequence<T>>) => Thunk<T>} */
96
- const flat = sequence => () => {
97
- const n = next(sequence)
96
+ /** @type {<I, O>(f: (result: ResultOne<I>) => Node<O>) => (input: Sequence<I>) => Thunk<O>} */
97
+ const nextMap = f => input => () => {
98
+ const n = next(input)
98
99
  if (n === undefined) { return undefined }
99
- const { first, tail } = n
100
- return [first, flat(tail)]
100
+ return f(n)
101
101
  }
102
102
 
103
+ /** @type {<T>(result: ResultOne<Sequence<T>>) => Node<T>} */
104
+ const flatFn = ({first, tail}) => [first, flat(tail)]
105
+
106
+ /** @type {<T>(sequence: Sequence<Sequence<T>>) => Thunk<T>} */
107
+ const flat = nextMap(flatFn)
108
+
103
109
  /** @type {<T>(...array: readonly Sequence<T>[]) => Thunk<T>} */
104
110
  const concat = (...array) => flat(array)
105
111
 
112
+ /** @type {<I, O>(f: (value: I) => O) => (result: ResultOne<I>) => Node<O>} */
113
+ const mapFn = f => ({ first, tail }) => ({ first: f(first), tail: map(f)(tail) })
114
+
106
115
  /** @type {<I, O>(f: (value: I) => O) => (input: Sequence<I>) => Thunk<O>} */
107
- const map = f => sequence => () => {
108
- const n = next(sequence)
109
- if (n === undefined) { return undefined }
110
- const { first, tail } = n
111
- return { first: f(first), tail: map(f)(tail) }
112
- }
116
+ const map = f => nextMap(mapFn(f))
113
117
 
114
118
  /** @type {<I, O>(f: (value: I) => Sequence<O>) => (input: Sequence<I>) => Thunk<O>} */
115
- const flatMap = f => sequence => flat(map(f)(sequence))
119
+ const flatMap = f => compose(map(f))(flat)
116
120
 
117
- /** @type {<T>(f: (value: T) => boolean) => (input: Sequence<T>) => Thunk<T>} */
118
- const filter = f => sequence => () => {
119
- const n = next(sequence)
120
- if (n === undefined) { return undefined }
121
- const { first, tail } = n
121
+ /** @type {<T>(f: (value: T) => boolean) => (result: ResultOne<T>) => Node<T>} */
122
+ const filterFn = f => ({ first, tail }) => {
122
123
  const fTail = filter(f)(tail)
123
124
  return f(first) ? { first, tail: fTail } : fTail()
124
125
  }
125
126
 
126
- /** @type {<I, O>(f: (value: I) => O|undefined) => (input: Sequence<I>) => Thunk<O>} */
127
- const filterMap = f => sequence => () => {
128
- const n = next(sequence)
129
- if (n === undefined) { return undefined }
130
- const { first, tail } = n
127
+ /** @type {<T>(f: (value: T) => boolean) => (input: Sequence<T>) => Thunk<T>} */
128
+ const filter = f => nextMap(filterFn(f))
129
+
130
+ /** @type {<I, O>(f: (value: I) => O|undefined) => (result: ResultOne<I>) => Node<O>} */
131
+ const filterMapFn = f => ({first, tail}) => {
131
132
  const fFirst = f(first)
132
133
  const fTail = filterMap(f)(tail)
133
134
  return fFirst === undefined ? fTail() : { first: fFirst, tail: fTail }
134
135
  }
135
136
 
137
+ /** @type {<I, O>(f: (value: I) => O|undefined) => (input: Sequence<I>) => Thunk<O>} */
138
+ const filterMap = f => nextMap(filterMapFn(f))
139
+
136
140
  /** @type {<T>(f: (value: T) => boolean) => (input: Sequence<T>) => Thunk<T>} */
137
141
  const takeWhile = f => input => () => {
138
142
  const result = next(input)
@@ -248,6 +252,12 @@ const sum = fold(addition)(0)
248
252
  /** @type {(separator: string) => (input: Sequence<string>) => string} */
249
253
  const join = separator => fold(op.join(separator))('')
250
254
 
255
+ /** @type {(a: number) => () => number} */
256
+ const counter = a => () => a + 1
257
+
258
+ /** @type {<T>(input: Sequence<T>) => number} */
259
+ const length = reduce(counter)(0)
260
+
251
261
  /**
252
262
  * @template T
253
263
  * @typedef {readonly[number, T]} Entry
@@ -311,5 +321,7 @@ module.exports = {
311
321
  /** @readonly */
312
322
  entries,
313
323
  /** @readonly */
324
+ length,
325
+ /** @readonly */
314
326
  countdown,
315
327
  }
package/sequence/test.js CHANGED
@@ -135,7 +135,7 @@ const stress = () => {
135
135
  }
136
136
  }
137
137
 
138
- //stress()
138
+ stress()
139
139
 
140
140
  module.exports = {
141
141