functionalscript 0.0.228 → 0.0.229

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.228",
3
+ "version": "0.0.229",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/sequence/index.js CHANGED
@@ -34,6 +34,9 @@ const op = require('../function/operator')
34
34
 
35
35
  const empty = () => undefined
36
36
 
37
+ /** @type {<T>(first: T) => (tail: Sequence<T>) => Sequence<T>} */
38
+ const create = first => tail => () => ({ first, tail })
39
+
37
40
  /** @type {<T>(sequence: Sequence<T>) => Node<T>} */
38
41
  const nodeOne = sequence => [empty, sequence]
39
42
 
@@ -136,23 +139,20 @@ const filterMapFn = f => ({first, tail}) => {
136
139
  /** @type {<I, O>(f: (value: I) => O|undefined) => (input: Sequence<I>) => Thunk<O>} */
137
140
  const filterMap = f => nextMap(filterMapFn(f))
138
141
 
142
+ /** @type {<T>(f: (value: T) => boolean) => (result: ResultOne<T>) => Node<T>} */
143
+ const takeWhileFn = f => ({ first, tail }) => f(first) ? { first, tail: takeWhile(f)(tail) } :undefined
144
+
139
145
  /** @type {<T>(f: (value: T) => boolean) => (input: Sequence<T>) => Thunk<T>} */
140
- const takeWhile = f => input => () => {
141
- const result = next(input)
142
- if (result === undefined) { return undefined }
146
+ const takeWhile = f => nextMap(takeWhileFn(f))
147
+
148
+ /** @type {<T>(f: (value: T) => boolean) => (result: ResultOne<T>) => Node<T>} */
149
+ const dropWhileFn = f => result => {
143
150
  const { first, tail } = result
144
- if (!f(first)) { return undefined }
145
- return { first, tail: takeWhile(f)(result.tail) }
151
+ return f(first) ? nodeOne(dropWhile(f)(tail)) : result
146
152
  }
147
153
 
148
154
  /** @type {<T>(f: (value: T) => boolean) => (input: Sequence<T>) => Thunk<T>} */
149
- const dropWhile = f => input => () => {
150
- const result = next(input)
151
- if (result === undefined) { return undefined }
152
- const { first, tail } = result
153
- if (f(first)) { return nodeOne(dropWhile(f)(tail)) }
154
- return result
155
- }
155
+ const dropWhile = f => nextMap(dropWhileFn(f))
156
156
 
157
157
  /** @type {<D>(def: D) => <T>(input: Sequence<T>) => D|T} */
158
158
  const first = def => input => {
@@ -206,15 +206,15 @@ const countdown = count => () => {
206
206
  * @typedef {readonly[A, ScanFunc<T, A>]} ScanState
207
207
  */
208
208
 
209
- /** @type {<T,A>(operator: ScanFunc<T, A>) => (input: Sequence<T>) => Thunk<A>} */
210
- const scan = operator => input => () => {
211
- const result = next(input)
212
- if (result === undefined) { return undefined }
213
- const { first, tail } = result
214
- const r = operator(first)
215
- return { first: r[0], tail: scan(r[1])(tail) }
209
+ /** @type {<T,A>(operator: ScanFunc<T, A>) => (result: ResultOne<T>) => Node<A>} */
210
+ const scanFn = operator => ({first, tail}) => {
211
+ const [value, nextOperator] = operator(first)
212
+ return { first: value, tail: scan(nextOperator)(tail) }
216
213
  }
217
214
 
215
+ /** @type {<T,A>(operator: ScanFunc<T, A>) => (input: Sequence<T>) => Thunk<A>} */
216
+ const scan = operator => nextMap(scanFn(operator))
217
+
218
218
  /** @type {<T,A>(operator: ScanFunc<T, A>) => <D>(def: D)=> (input: Sequence<T>) => D|A} */
219
219
  const scanReduce = operator => def => input => last(def)(scan(operator)(input))
220
220
 
@@ -265,6 +265,12 @@ const entryOp = index => value => [[index, value], entryOp(index + 1)]
265
265
  /** @type {<T>(input: Sequence<T>) => Thunk<Entry<T>>} */
266
266
  const entries = scan(entryOp(0))
267
267
 
268
+ /** @type {<T>(prior: Sequence<T>) => (value: T) => Sequence<T>} */
269
+ const reverseOp = prior => value => create(value)(prior)
270
+
271
+ /** @type {<T>(input: Sequence<T>) => Sequence<T>} */
272
+ const reverse = reduce(reverseOp)(empty)
273
+
268
274
  module.exports = {
269
275
  /** @readonly */
270
276
  empty,
@@ -321,5 +327,7 @@ module.exports = {
321
327
  /** @readonly */
322
328
  length,
323
329
  /** @readonly */
330
+ reverse,
331
+ /** @readonly */
324
332
  countdown,
325
333
  }
package/sequence/test.js CHANGED
@@ -92,6 +92,16 @@ const stringify = sequence => json.stringify(sort)(_.toArray(sequence))
92
92
  if (result !== '[[0,"hello"],[1,"world"]]') { throw result }
93
93
  }
94
94
 
95
+ {
96
+ const result = stringify(_.reverse([]))
97
+ if (result !== '[]') { throw result }
98
+ }
99
+
100
+ {
101
+ const result = stringify(_.reverse([1,2,3,4,5]))
102
+ if (result !== '[5,4,3,2,1]') { throw result }
103
+ }
104
+
95
105
  // stress tests
96
106
 
97
107
  const stress = () => {