functionalscript 0.0.222 → 0.0.224

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.222",
3
+ "version": "0.0.224",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/sequence/index.js CHANGED
@@ -19,7 +19,7 @@ const op = require('../function/operator')
19
19
 
20
20
  /**
21
21
  * @template T
22
- * @typedef { readonly[Sequence<T>, Sequence<T>] } Concat<T>
22
+ * @typedef { readonly[Sequence<T>, Sequence<T>]} Concat<T>
23
23
  */
24
24
 
25
25
  /**
@@ -34,6 +34,9 @@ const op = require('../function/operator')
34
34
 
35
35
  const empty = () => undefined
36
36
 
37
+ /** @type {<T>(sequence: Sequence<T>) => Node<T>} */
38
+ const nodeOne = sequence => [empty, sequence]
39
+
37
40
  /** @type {<T>(array: readonly T[]) => Result<T>} */
38
41
  const fromArray = array => {
39
42
  /** @typedef {typeof array extends readonly(infer T)[] ? T : never} T */
@@ -48,27 +51,23 @@ const fromArray = array => {
48
51
  /** @type {<T>(sequence: Sequence<T>) => Node<T>} */
49
52
  const node = sequence => sequence instanceof Array ? fromArray(sequence) : sequence()
50
53
 
51
- /** @type {<T>(concat: Concat<T>) => Sequence<T>} */
52
- const concatNext = ([a, b]) => {
53
- const result = node(a)
54
- if (result === undefined) {
55
- return b
56
- } else if (result instanceof Array) {
57
- const [aa, ab] = result
58
- return () => [aa, () => [ab, b]]
59
- } else {
60
- const { first, tail } = result
61
- return () => ({ first, tail: () => [tail, b] })
62
- }
63
- }
64
-
65
54
  /** @type {<T>(sequence: Sequence<T>) => Result<T>} */
66
55
  const next = sequence => {
67
56
  let i = sequence
68
57
  while (true) {
69
58
  const n = node(i)
70
59
  if (!(n instanceof Array)) { return n }
71
- i = concatNext(n)
60
+ const [a, b] = n
61
+ const result = node(a)
62
+ if (result === undefined) {
63
+ i = b
64
+ } else if (result instanceof Array) {
65
+ const [aa, ab] = result
66
+ i = () => [aa, () => [ab, b]]
67
+ } else {
68
+ const { first, tail } = result
69
+ return { first, tail: () => [tail, b] }
70
+ }
72
71
  }
73
72
  }
74
73
 
@@ -121,7 +120,7 @@ const flatMap = f => compose(map(f))(flat)
121
120
  /** @type {<T>(f: (value: T) => boolean) => (result: ResultOne<T>) => Node<T>} */
122
121
  const filterFn = f => ({ first, tail }) => {
123
122
  const fTail = filter(f)(tail)
124
- return f(first) ? { first, tail: fTail } : fTail()
123
+ return f(first) ? { first, tail: fTail } : nodeOne(fTail)
125
124
  }
126
125
 
127
126
  /** @type {<T>(f: (value: T) => boolean) => (input: Sequence<T>) => Thunk<T>} */
@@ -131,7 +130,7 @@ const filter = f => nextMap(filterFn(f))
131
130
  const filterMapFn = f => ({first, tail}) => {
132
131
  const fFirst = f(first)
133
132
  const fTail = filterMap(f)(tail)
134
- return fFirst === undefined ? fTail() : { first: fFirst, tail: fTail }
133
+ return fFirst === undefined ? nodeOne(fTail) : { first: fFirst, tail: fTail }
135
134
  }
136
135
 
137
136
  /** @type {<I, O>(f: (value: I) => O|undefined) => (input: Sequence<I>) => Thunk<O>} */
@@ -148,14 +147,11 @@ const takeWhile = f => input => () => {
148
147
 
149
148
  /** @type {<T>(f: (value: T) => boolean) => (input: Sequence<T>) => Thunk<T>} */
150
149
  const dropWhile = f => input => () => {
151
- let i = input
152
- while (true) {
153
- const result = next(i)
154
- if (result === undefined) { return undefined }
155
- const { first, tail } = result
156
- if (!f(first)) return result
157
- i = tail
158
- }
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
159
155
  }
160
156
 
161
157
  /** @type {<D>(def: D) => <T>(input: Sequence<T>) => D|T} */
@@ -293,6 +289,8 @@ module.exports = {
293
289
  /** @readonly */
294
290
  filter,
295
291
  /** @readonly */
292
+ filterMap,
293
+ /** @readonly */
296
294
  find,
297
295
  /** @readonly */
298
296
  some,
package/sequence/test.js CHANGED
@@ -95,6 +95,18 @@ const stringify = sequence => json.stringify(sort)(_.toArray(sequence))
95
95
  // stress tests
96
96
 
97
97
  const stress = () => {
98
+
99
+ {
100
+ // 100_000_000 is too much
101
+ const n = 50_000_000
102
+ const result = _.toArray(_.countdown(n))
103
+ if (result.length !== n) { throw result.length }
104
+ const len = _.length(_.filter(x => x > n)(result))
105
+ if (len !== 0) { throw len }
106
+ }
107
+
108
+ console.log('first')
109
+
98
110
  {
99
111
  // 200_000_000 is too much
100
112
  const n = 100_000_000
@@ -133,6 +145,17 @@ const stress = () => {
133
145
  }
134
146
  const a = _.next(sequence)
135
147
  }
148
+
149
+ console.log('filterMap')
150
+
151
+ {
152
+ // 100_000_000 is too much
153
+ const n = 50_000_000
154
+ const result = _.toArray(_.countdown(n))
155
+ if (result.length !== n) { throw result.length }
156
+ const len = _.length(_.filterMap(() => undefined)(result))
157
+ if (len !== 0) { throw len }
158
+ }
136
159
  }
137
160
 
138
161
  stress()