functionalscript 0.0.173 → 0.0.174

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/btree/index.js CHANGED
@@ -336,7 +336,7 @@ const values = node => ({
336
336
  const flatArray = (...array) => list.flat(list.fromArray(array))
337
337
 
338
338
  /** @type {<T>(node: Node<T>) => list.List<T>} */
339
- const valuesList = node => {
339
+ const valuesList = node => () => {
340
340
  const f = () => {
341
341
  switch (node.length) {
342
342
  case 1: case 2: { return list.fromArray(node) }
@@ -358,7 +358,7 @@ const valuesList = node => {
358
358
  }
359
359
  }
360
360
  }
361
- return f()
361
+ return f()()
362
362
  }
363
363
 
364
364
  module.exports = {
package/btree/test.js CHANGED
@@ -23,7 +23,8 @@ const test = () => {
23
23
  /** @type {import('../sequence/list').Result<string>} */
24
24
  let result = valuesList(node)()
25
25
  while (result !== undefined) {
26
- console.log(result[0])
26
+ const t = result[0]
27
+ console.log(t)
27
28
  result = result[1]()
28
29
  }
29
30
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.173",
3
+ "version": "0.0.174",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -85,8 +85,8 @@ const splitLast = a => {
85
85
  return option.map(split)(last(a))
86
86
  }
87
87
 
88
- /** @type {<T>(a: Array<T>) => (index: number) => readonly[T]|undefined} */
89
- const at = a => index => index < a.length ? [a[index]] : undefined
88
+ /** @type {(index: number) => <T>(a: Array<T>) => readonly[T]|undefined} */
89
+ const at = index => a => index < a.length ? [a[index]] : undefined
90
90
 
91
91
  module.exports = {
92
92
  /** @readonly */
@@ -56,12 +56,12 @@ const scan = s => c => ({
56
56
  })
57
57
 
58
58
  /** @type {<T, R>(s: seq.InclusiveScan<T, R>) => (c: AsyncOrSyncIterable<T>) => AsyncIterable<R>} */
59
- const inclusiveScan = s => c => concat([s.first])(scan(s.scan)(c))
59
+ const inclusiveScan = ([first, s]) => c => concat([first])(scan(s)(c))
60
60
 
61
61
  /** @type {<T, R>(is: seq.InclusiveScan<T, R>) => (c: AsyncOrSyncIterable<T>) => Promise<R>} */
62
- const reduce = is => async c => {
63
- let next = is.first
64
- for await (const i of scan(is.scan)(c)) {
62
+ const reduce = ([first, s]) => async c => {
63
+ let next = first
64
+ for await (const i of scan(s)(c)) {
65
65
  next = i
66
66
  }
67
67
  return next
@@ -71,7 +71,7 @@ const sum = reduce(seq.sum)
71
71
 
72
72
  const join = pipe(seq.join)(reduce)
73
73
 
74
- const size = reduce(seq.size)
74
+ const length = reduce(seq.length)
75
75
 
76
76
  /** @type {<T>(f: (value: T) => boolean) => (c: AsyncOrSyncIterable<T>) => AsyncIterable<T>} */
77
77
  const takeWhile = f => c => ({
@@ -99,7 +99,7 @@ module.exports = {
99
99
  /** @readonly */
100
100
  sum,
101
101
  /** @readonly */
102
- size,
102
+ length,
103
103
  /** @readonly */
104
104
  join,
105
105
  /** @readonly */
package/sequence/index.js CHANGED
@@ -22,10 +22,7 @@ const { id } = require('../function')
22
22
  /**
23
23
  * @template T
24
24
  * @template R
25
- * @typedef {{
26
- * readonly scan: Scan<T, R>
27
- * readonly first: R
28
- * }} InclusiveScan
25
+ * @typedef {Tuple2<R, Scan<T, R>>} InclusiveScan
29
26
  */
30
27
 
31
28
  /** @type {<R, T>(operator: op.BinaryOperator<R, T>) => (prior: R) => Scan<T, R>} */
@@ -42,10 +39,7 @@ const scan = operator => {
42
39
  }
43
40
 
44
41
  /** @type {<R, T>(operator: op.BinaryOperator<R, T>) => (first: R) => InclusiveScan<T, R>} */
45
- const inclusiveScan = operator => first => ({
46
- scan: scan(operator)(first),
47
- first,
48
- })
42
+ const inclusiveScan = operator => first => [first, scan(operator)(first)]
49
43
 
50
44
  /**
51
45
  * @template T
@@ -58,14 +52,11 @@ const createEntries = index => value => [[index, value], createEntries(index + 1
58
52
  const entries = createEntries(0)
59
53
 
60
54
  /** @type {(separator: string) => InclusiveScan<string, string>} */
61
- const join = separator => ({
62
- scan: value => [value, scan(op.join(separator))(value)],
63
- first: ''
64
- })
55
+ const join = separator => ['', value => [value, scan(op.join(separator))(value)]]
65
56
 
66
57
  const sum = inclusiveScan(op.addition)(0)
67
58
 
68
- const size = inclusiveScan(a => () => a + 1)(0)
59
+ const length = inclusiveScan(a => () => a + 1)(0)
69
60
 
70
61
  /**
71
62
  * @template T
@@ -89,7 +80,7 @@ module.exports = {
89
80
  /** @readonly */
90
81
  sum,
91
82
  /** @readonly */
92
- size,
83
+ length,
93
84
  /** @readonly */
94
85
  entries,
95
86
  /** @readonly */
@@ -22,12 +22,12 @@ const scan = s => c => ({
22
22
  })
23
23
 
24
24
  /** @type {<T, R>(s: seq.InclusiveScan<T, R>) => (c: Iterable<T>) => Iterable<R>} */
25
- const inclusiveScan = s => c => concat([s.first])(scan(s.scan)(c))
25
+ const inclusiveScan = ([first, s]) => c => concat([first])(scan(s)(c))
26
26
 
27
27
  /** @type {<T, R>(s: seq.InclusiveScan<T, R>) => (c: Iterable<T>) => R} */
28
- const reduce = s => c => {
29
- let next = s.first
30
- for (const i of scan(s.scan)(c)) {
28
+ const reduce = ([first, s]) => c => {
29
+ let next = first
30
+ for (const i of scan(s)(c)) {
31
31
  next = i
32
32
  }
33
33
  return next
@@ -37,7 +37,7 @@ const entries = scan(seq.entries)
37
37
 
38
38
  const sum = reduce(seq.sum)
39
39
 
40
- const size = reduce(seq.size)
40
+ const length = reduce(seq.length)
41
41
 
42
42
  const join = pipe(seq.join)(reduce)
43
43
 
@@ -87,7 +87,7 @@ module.exports = {
87
87
  /** @readonly */
88
88
  sum,
89
89
  /** @readonly */
90
- size,
90
+ length,
91
91
  /** @readonly */
92
92
  entries,
93
93
  /** @readonly */
@@ -1,5 +1,7 @@
1
1
  const array = require('../array')
2
2
  const option = require('../../option')
3
+ const base = require('..')
4
+ const { pipe } = require('../../function')
3
5
 
4
6
  /**
5
7
  * @template T
@@ -21,10 +23,10 @@ const empty = () => undefined
21
23
  /**
22
24
  * @template T
23
25
  * @template R
24
- * @typedef {(list: List<T>) => List<R>} Map
26
+ * @typedef {(list: List<T>) => List<R>} ListMap
25
27
  */
26
28
 
27
- /** @type {<T>(first: T) => Map<T, T>} */
29
+ /** @type {<T>(first: T) => ListMap<T, T>} */
28
30
  const list = first => tail => () => [first, tail]
29
31
 
30
32
  /** @type {<T>(first: T) => List<T>} */
@@ -34,43 +36,89 @@ const one = first => list(first)(empty)
34
36
  const fromArray = a => {
35
37
  /** @typedef {typeof a extends array.Array<infer T> ? T : never} T */
36
38
  /** @type {(index: number) => List<T>} */
37
- const listFrom = index => {
39
+ const at = index => {
38
40
  /** @type {(value: readonly [T]) => Result<T>} */
39
- const result = ([value]) => list(value)(listFrom(index + 1))()
40
- return () => option.map(result)(array.at(a)(index))
41
+ const result = ([value]) => list(value)(at(index + 1))()
42
+ return () => option.map(result)(array.at(index)(a))
41
43
  }
42
- return listFrom(0)
44
+ return at(0)
43
45
  }
44
46
 
45
- /** @type {<T>(list0: List<T>) => Map<T, T>} */
46
- const concat = list0 => list1 => () => {
47
- /** @typedef {typeof list0 extends List<infer T> ? T : never} T */
47
+ /** @type {<T>(list0: List<T>) => ListMap<T, T>} */
48
+ const concat = a => b => () => {
49
+ /** @typedef {typeof a extends List<infer T> ? T : never} T */
48
50
  /** @type {(firstAntTail: FirstAndTail<T>) => Result<T>} */
49
- const result = ([first, tail]) => [first, concat(tail)(list1)]
50
- return option.map(result)(list0())
51
+ const defined = ([first, tail]) => [first, concat(tail)(b)]
52
+ return option.match(defined)(b)(a())
51
53
  }
52
54
 
53
- /** @type {<T, R>(f: (value: T) => List<R>) => Map<T, R>} */
55
+ /** @type {<T, R>(f: (value: T) => List<R>) => ListMap<T, R>} */
54
56
  const flatMap = f => {
55
57
  /** @typedef {typeof f extends (value: infer T) => List<infer R> ? [T, R] : never} TR */
56
58
  /** @typedef {TR[0]} T */
57
59
  /** @typedef {TR[1]} R */
58
60
  /** @type {(firstAntTail: FirstAndTail<T>) => Result<R>} */
59
- const result = ([first, tail]) => concat(f(first))(map(tail))()
61
+ const defined = ([first, tail]) => concat(f(first))(listMap(tail))()
60
62
  /** @type {(list: List<T>) => List<R>} */
61
- const map = list => () => option.map(result)(list())
62
- return map
63
+ const listMap = list => () => option.map(defined)(list())
64
+ return listMap
63
65
  }
64
66
 
65
67
  /** @type {<T>(list: List<List<T>>) => List<T>} */
66
68
  const flat = flatMap(i => i)
67
69
 
68
- /** @type {<T, R>(f: (value: T) => R) => Map<T, R>} */
70
+ /** @type {<T, R>(f: (value: T) => R) => ListMap<T, R>} */
69
71
  const map = f => flatMap(i => one(f(i)))
70
72
 
71
- /** @type {<T>(f: (value: T) => boolean) => Map<T, T>} */
73
+ /** @type {<T>(f: (value: T) => boolean) => ListMap<T, T>} */
72
74
  const filter = f => flatMap(i => f(i) ? one(i) : empty)
73
75
 
76
+ /** @type {<T, R>(s: base.Scan<T, R>) => ListMap<T, R>} */
77
+ const scan = s => input => () => {
78
+ /** @typedef {typeof s extends base.Scan<infer T, infer R> ? [T, R] : never} TR */
79
+ /** @typedef {TR[0]} T */
80
+ /** @typedef {TR[1]} R */
81
+ /** @type {(firstAndTail: FirstAndTail<T>) => Result<R>} */
82
+ const defined = ([first, tail]) => {
83
+ const [newFirst, newS] = s(first)
84
+ return [newFirst, scan(newS)(tail)]
85
+ }
86
+ return option.map(defined)(input())
87
+ }
88
+
89
+ /** @type {<T, R>(s: base.InclusiveScan<T, R>) => ListMap<T, R>} */
90
+ const inclusiveScan = ([first, s]) => input => list(first)(scan(s)(input))
91
+
92
+ /** @type {<T>(def: T) => (input: List<T>) => T} */
93
+ const last = def => input => {
94
+ let i = input()
95
+ let r = def
96
+ while (i !== undefined) {
97
+ r = i[0]
98
+ i = i[1]()
99
+ }
100
+ return r
101
+ }
102
+
103
+ /** @type {<T, R>(s: base.InclusiveScan<T, R>) => (input: List<T>) => R} */
104
+ const reduce = s => input => last(s[0])(inclusiveScan(s)(input))
105
+
106
+ const entries = scan(base.entries)
107
+
108
+ const sum = reduce(base.sum)
109
+
110
+ const length = reduce(base.length)
111
+
112
+ const join = pipe(base.join)(reduce)
113
+
114
+ /** @type {<T>(f: (value: T) => boolean) => (input: List<T>) => T|undefined} */
115
+ const find = f => input => {
116
+ /** @typedef {typeof f extends (value: infer T) => boolean ? T : never} T */
117
+ /** @type {(result: FirstAndTail<T>) => T} */
118
+ const defined = ([first]) => first
119
+ return option.map(defined)(filter(f)(input)())
120
+ }
121
+
74
122
  /**
75
123
  * Note: probably, it's possible to implement using the `scan` concept.
76
124
  * @type {<T>(list: List<T>) => Iterable<T>}
@@ -106,4 +154,22 @@ module.exports = {
106
154
  map,
107
155
  /** @readonly */
108
156
  filter,
157
+ /** @readonly */
158
+ scan,
159
+ /** @readonly */
160
+ inclusiveScan,
161
+ /** @readonly */
162
+ last,
163
+ /** @readonly */
164
+ reduce,
165
+ /** @readonly */
166
+ entries,
167
+ /** @readonly */
168
+ sum,
169
+ /** @readonly */
170
+ join,
171
+ /** @readonly */
172
+ length,
173
+ /** @readonly */
174
+ find,
109
175
  }
@@ -0,0 +1,24 @@
1
+ const list = require('.')
2
+ const { sum } = require('..')
3
+
4
+ /** @type {<T>(l: list.List<T>) => void} */
5
+ const print = a => {
6
+ let i = a()
7
+ while (i !== undefined) {
8
+ console.log(i[0])
9
+ i = i[1]()
10
+ }
11
+ }
12
+
13
+ {
14
+ const big = list.fromArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 42, 60])
15
+ print(big)
16
+ /*
17
+ const list0 = list.fromArray([0, 1, 2, 3])
18
+ const list1 = list.flatMap(x => list.fromArray([x, x * 2, x * 3]))(list0)
19
+ const list2 = list.concat(list0)(list0)
20
+ const list3 = list.inclusiveScan(sum)(list0)
21
+ print(list3)
22
+ const r = list.find(x => x === 42)(list.fromArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 42, 60]))
23
+ */
24
+ }
package/test.js CHANGED
@@ -1,5 +1,6 @@
1
1
  const i = require('./')
2
2
 
3
+ require('./sequence/list/test')
3
4
  require('./btree/test')
4
5
  require('./sequence/iterable/test')
5
6
  require('./sequence/asyncIterable/test')