scats 1.4.0-dev → 1.4.1-dev
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/dist/abstract-map.d.ts +4 -4
- package/dist/abstract-map.js +12 -15
- package/dist/abstract-set.d.ts +2 -2
- package/dist/abstract-set.js +6 -9
- package/dist/array-iterable.d.ts +1 -1
- package/dist/array-iterable.js +22 -26
- package/dist/collection.d.ts +4 -4
- package/dist/collection.js +50 -71
- package/dist/either.d.ts +4 -4
- package/dist/either.js +31 -39
- package/dist/hashmap.d.ts +2 -2
- package/dist/hashmap.js +9 -12
- package/dist/hashset.d.ts +3 -3
- package/dist/hashset.js +6 -11
- package/dist/index.d.ts +8 -8
- package/dist/index.js +9 -13
- package/dist/mappable.js +1 -2
- package/dist/mutable/hashmap.d.ts +3 -3
- package/dist/mutable/hashmap.js +3 -8
- package/dist/mutable/hashset.d.ts +2 -2
- package/dist/mutable/hashset.js +3 -8
- package/dist/mutable.d.ts +3 -3
- package/dist/mutable.js +3 -9
- package/dist/option.d.ts +6 -6
- package/dist/option.js +34 -44
- package/dist/try.d.ts +3 -3
- package/dist/try.js +27 -37
- package/dist/util.d.ts +2 -2
- package/dist/util.js +41 -50
- package/package.json +1 -1
- package/.eslintrc.cjs +0 -44
- package/coverage/clover.xml +0 -937
- package/coverage/coverage-final.json +0 -15
- package/coverage/lcov-report/array-iterable.ts.html +0 -1709
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -79
- package/coverage/lcov-report/collection.ts.html +0 -1475
- package/coverage/lcov-report/either.ts.html +0 -1934
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/hashmap.ts.html +0 -527
- package/coverage/lcov-report/hashset.ts.html +0 -392
- package/coverage/lcov-report/index.html +0 -126
- package/coverage/lcov-report/index.ts.html +0 -101
- package/coverage/lcov-report/option.ts.html +0 -758
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -170
- package/coverage/lcov-report/src/abstract-map.ts.html +0 -317
- package/coverage/lcov-report/src/abstract-set.ts.html +0 -200
- package/coverage/lcov-report/src/array-iterable.ts.html +0 -1751
- package/coverage/lcov-report/src/collection.ts.html +0 -1778
- package/coverage/lcov-report/src/either.ts.html +0 -1934
- package/coverage/lcov-report/src/hashmap.ts.html +0 -428
- package/coverage/lcov-report/src/hashset.ts.html +0 -482
- package/coverage/lcov-report/src/index.html +0 -276
- package/coverage/lcov-report/src/index.ts.html +0 -110
- package/coverage/lcov-report/src/mutable/hashmap.ts.html +0 -821
- package/coverage/lcov-report/src/mutable/hashset.ts.html +0 -611
- package/coverage/lcov-report/src/mutable/index.html +0 -126
- package/coverage/lcov-report/src/mutable.ts.html +0 -89
- package/coverage/lcov-report/src/option.ts.html +0 -758
- package/coverage/lcov-report/src/try.ts.html +0 -923
- package/coverage/lcov-report/src/util.ts.html +0 -518
- package/coverage/lcov-report/try.ts.html +0 -923
- package/coverage/lcov-report/util.ts.html +0 -518
- package/coverage/lcov.info +0 -2223
- package/jest.config.js +0 -32
- package/src/abstract-map.ts +0 -79
- package/src/abstract-set.ts +0 -40
- package/src/array-iterable.ts +0 -557
- package/src/collection.ts +0 -619
- package/src/either.ts +0 -618
- package/src/hashmap.ts +0 -116
- package/src/hashset.ts +0 -134
- package/src/index.ts +0 -10
- package/src/mappable.ts +0 -8
- package/src/mutable/hashmap.ts +0 -247
- package/src/mutable/hashset.ts +0 -177
- package/src/mutable.ts +0 -3
- package/src/option.ts +0 -226
- package/src/try.ts +0 -281
- package/src/util.ts +0 -146
package/src/either.ts
DELETED
|
@@ -1,618 +0,0 @@
|
|
|
1
|
-
import {none, Option, some} from './option';
|
|
2
|
-
import {Collection, Nil} from './collection';
|
|
3
|
-
import {failure, success, TryLike} from './try';
|
|
4
|
-
import {toErrorConversion} from './util';
|
|
5
|
-
import {Mappable} from './mappable';
|
|
6
|
-
|
|
7
|
-
export interface EitherMatch<LEFT, RIGHT, T> {
|
|
8
|
-
right: (right: RIGHT) => T;
|
|
9
|
-
left: (left: LEFT) => T;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export abstract class Either<LEFT, RIGHT> implements Mappable<RIGHT> {
|
|
13
|
-
|
|
14
|
-
abstract match<T>(matcher: EitherMatch<LEFT, RIGHT, T>): T;
|
|
15
|
-
|
|
16
|
-
/** Returns `true` if this is a `Left`, `false` otherwise.
|
|
17
|
-
*
|
|
18
|
-
* ```
|
|
19
|
-
* left("tulip").isLeft // true
|
|
20
|
-
* right("venus fly-trap").isLeft // false
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
abstract get isLeft(): boolean;
|
|
24
|
-
|
|
25
|
-
/** Returns `true` if this is a `Right`, `false` otherwise.
|
|
26
|
-
*
|
|
27
|
-
* ```
|
|
28
|
-
* Left("tulip").isRight // false
|
|
29
|
-
* Right("venus fly-trap").isRight // true
|
|
30
|
-
* ```
|
|
31
|
-
*/
|
|
32
|
-
get isRight(): boolean {
|
|
33
|
-
return !this.isLeft;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/** Projects this `Either` as a `Left`.
|
|
37
|
-
*
|
|
38
|
-
* This allows for-comprehensions over the left side of `Either` instances,
|
|
39
|
-
* reversing `Either`'s usual right-bias.
|
|
40
|
-
*
|
|
41
|
-
* For example ```
|
|
42
|
-
* forComprehension(
|
|
43
|
-
* step('s', () => left("flower").left)
|
|
44
|
-
* ).yield(state => state.s.length) // Left(6)
|
|
45
|
-
* ```
|
|
46
|
-
*
|
|
47
|
-
* Continuing the analogy with [[Option]], a `LeftProjection` declares
|
|
48
|
-
* that `Left` should be analogous to `Some` in some code.
|
|
49
|
-
*
|
|
50
|
-
* ```
|
|
51
|
-
* // using Option
|
|
52
|
-
* function interactWithDB(x: Query): Option<Result> {
|
|
53
|
-
* try {
|
|
54
|
-
* return some(getResultFromDatabase(x));
|
|
55
|
-
* }
|
|
56
|
-
* catch(e) {
|
|
57
|
-
* return none;
|
|
58
|
-
* }
|
|
59
|
-
* }
|
|
60
|
-
*
|
|
61
|
-
* // this will only be executed if interactWithDB returns a Some
|
|
62
|
-
* const report = forComprehension(
|
|
63
|
-
* step('result', () => interactWithDB(someQuery))
|
|
64
|
-
* ).yield(state => generateReport(state.result));
|
|
65
|
-
*
|
|
66
|
-
* report.match({
|
|
67
|
-
* some: (r) => send(r),
|
|
68
|
-
* none: () => console.log("report not generated, not sure why...")
|
|
69
|
-
* })
|
|
70
|
-
*
|
|
71
|
-
* // using Either
|
|
72
|
-
* function interactWithDB(x: Query): Either<Exception, Result> =
|
|
73
|
-
* try {
|
|
74
|
-
* return right(getResultFromDatabase(x));
|
|
75
|
-
* }
|
|
76
|
-
* catch(e) {
|
|
77
|
-
* return left(e);
|
|
78
|
-
* }
|
|
79
|
-
* }
|
|
80
|
-
*
|
|
81
|
-
* // run a report only if interactWithDB returns a Right
|
|
82
|
-
* const report = forComprehension(
|
|
83
|
-
* step('result', () => interactWithDB(someQuery))
|
|
84
|
-
* ).yield(state => generateReport(state.result));
|
|
85
|
-
*
|
|
86
|
-
* report.match({
|
|
87
|
-
* right: (r) => send(r),
|
|
88
|
-
* left: (e) => console.log(`report not generated, reason was ${e}`)
|
|
89
|
-
* })
|
|
90
|
-
*
|
|
91
|
-
* // only report errors
|
|
92
|
-
* forComprehension(
|
|
93
|
-
* step('e', () => interactWithDB('1').left)
|
|
94
|
-
* ).yield(state => console.log(`query failed, reason was ${state.e}`));
|
|
95
|
-
* ```
|
|
96
|
-
*/
|
|
97
|
-
get left(): Either.LeftProjection<LEFT, RIGHT> {
|
|
98
|
-
return new Either.LeftProjection(this);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
/** Applies `fa` if this is a `Left` or `fb` if this is a `Right`.
|
|
103
|
-
*
|
|
104
|
-
* @example ```
|
|
105
|
-
* const result = Try(() => {throw Error('error')}).toEither
|
|
106
|
-
* result.fold(
|
|
107
|
-
* e => `Operation failed with ${e.message}`,
|
|
108
|
-
* v => `Operation produced value: ${v}`
|
|
109
|
-
* )
|
|
110
|
-
* ```
|
|
111
|
-
*
|
|
112
|
-
* @param fa the function to apply if this is a `Left`
|
|
113
|
-
* @param fb the function to apply if this is a `Right`
|
|
114
|
-
* @return the results of applying the function
|
|
115
|
-
*/
|
|
116
|
-
fold<C>(fa: (left: LEFT) => C, fb: (right: RIGHT) => C): C {
|
|
117
|
-
return this.match({
|
|
118
|
-
right: v => fb(v),
|
|
119
|
-
left: e => fa(e)
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/** If this is a `Left`, then return the left value in `Right` or vice versa.
|
|
124
|
-
*
|
|
125
|
-
* @example
|
|
126
|
-
* ```
|
|
127
|
-
* const left: Either<string, number> = left("left")
|
|
128
|
-
* const right: Either<number, string> = left.swap // Result: Right("left")
|
|
129
|
-
* ```
|
|
130
|
-
*/
|
|
131
|
-
get swap(): Either<RIGHT, LEFT> {
|
|
132
|
-
return this.match<Either<RIGHT, LEFT>>({
|
|
133
|
-
right: v => left(v),
|
|
134
|
-
left: e => right(e)
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
/** Executes the given side-effecting function if this is a `Right`.
|
|
140
|
-
*
|
|
141
|
-
* ```
|
|
142
|
-
* right(12).foreach(x => console.log(x)) // prints "12"
|
|
143
|
-
* left(12).foreach(x => console.log(x)) // doesn't print
|
|
144
|
-
* ```
|
|
145
|
-
* @param f The side-effecting function to execute.
|
|
146
|
-
*/
|
|
147
|
-
foreach(f: (right: RIGHT) => void): void {
|
|
148
|
-
this.match<void>({
|
|
149
|
-
right: b => f(b),
|
|
150
|
-
left: () => {
|
|
151
|
-
// do nothing.
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
/** Returns the value from this `Right` or the given argument if this is a `Left`.
|
|
158
|
-
*
|
|
159
|
-
* ```
|
|
160
|
-
* right(12).getOrElse(() => 17) // 12
|
|
161
|
-
* left(12).getOrElse(() => 17) // 17
|
|
162
|
-
* ```
|
|
163
|
-
*/
|
|
164
|
-
getOrElse(or: () => RIGHT): RIGHT {
|
|
165
|
-
return this.match({
|
|
166
|
-
right: b => b,
|
|
167
|
-
left: () => or()
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/** Returns the value from this `Right` or the given argument if this is a `Left`.
|
|
172
|
-
*
|
|
173
|
-
* ```
|
|
174
|
-
* right(12).getOrElseValue(17) // 12
|
|
175
|
-
* left(12).getOrElseValue(17) // 17
|
|
176
|
-
* ```
|
|
177
|
-
*/
|
|
178
|
-
getOrElseValue(or: RIGHT): RIGHT {
|
|
179
|
-
return this.match({
|
|
180
|
-
right: b => b,
|
|
181
|
-
left: () => or
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/** Returns this `Right` or the given argument if this is a `Left`.
|
|
186
|
-
*
|
|
187
|
-
* ```
|
|
188
|
-
* right(1).orElse(() => left(2)) // right(1)
|
|
189
|
-
* left(1).orElse(() => left(2)) // left(2)
|
|
190
|
-
* left(1).orElse(() => left(2)).orElse(() => right(3)) // right(3)
|
|
191
|
-
* ```
|
|
192
|
-
*/
|
|
193
|
-
orElse(or: () => Either<LEFT, RIGHT>): Either<LEFT, RIGHT> {
|
|
194
|
-
return this.match({
|
|
195
|
-
right: () => this,
|
|
196
|
-
left: () => or()
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/** Returns this `Right` or the given argument if this is a `Left`.
|
|
201
|
-
*
|
|
202
|
-
* ```
|
|
203
|
-
* right(1).orElseValue(left(2)) // right(1)
|
|
204
|
-
* left(1).orElseValue(left(2)) // left(2)
|
|
205
|
-
* left(1).orElseValue(left(2)).orElseValue(right(3)) // right(3)
|
|
206
|
-
* ```
|
|
207
|
-
*/
|
|
208
|
-
orElseValue(or: Either<LEFT, RIGHT>): Either<LEFT, RIGHT> {
|
|
209
|
-
return this.match({
|
|
210
|
-
right: () => this,
|
|
211
|
-
left: () => or
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
/** Returns `true` if this is a `Right` and its value is equal to `elem` (as determined by `===`),
|
|
217
|
-
* returns `false` otherwise.
|
|
218
|
-
*
|
|
219
|
-
* ```
|
|
220
|
-
* // Returns true because value of Right is "something" which equals "something".
|
|
221
|
-
* Right("something") contains "something"
|
|
222
|
-
*
|
|
223
|
-
* // Returns false because value of Right is "something" which does not equal "anything".
|
|
224
|
-
* Right("something") contains "anything"
|
|
225
|
-
*
|
|
226
|
-
* // Returns false because it's not a Right value.
|
|
227
|
-
* Left("something") contains "something"
|
|
228
|
-
* ```
|
|
229
|
-
*
|
|
230
|
-
* @param elem the element to test.
|
|
231
|
-
* @return `true` if this is a `Right` value `===` to `elem`.
|
|
232
|
-
*/
|
|
233
|
-
contains(elem: RIGHT): boolean {
|
|
234
|
-
return this.match({
|
|
235
|
-
right: b => elem === b,
|
|
236
|
-
left: () => false
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/** Returns `true` if `Left` or returns the result of the application of
|
|
241
|
-
* the given predicate to the `Right` value.
|
|
242
|
-
*
|
|
243
|
-
* ```
|
|
244
|
-
* right(12).forall(_ => _ > 10) // true
|
|
245
|
-
* right(7).forall(_ => _ > 10) // false
|
|
246
|
-
* left(12).forall(_ => false) // true
|
|
247
|
-
* ```
|
|
248
|
-
*/
|
|
249
|
-
forall(f: (right: RIGHT) => boolean): boolean {
|
|
250
|
-
return this.match({
|
|
251
|
-
right: b => f(b),
|
|
252
|
-
left: () => true
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
/** Returns `false` if `Left` or returns the result of the application of
|
|
258
|
-
* the given predicate to the `Right` value.
|
|
259
|
-
*
|
|
260
|
-
* ```
|
|
261
|
-
* right(12).exists(_ => _ > 10) // true
|
|
262
|
-
* right(7).exists(_ => _ > 10) // false
|
|
263
|
-
* left(12).exists(_ => true) // false
|
|
264
|
-
* ```
|
|
265
|
-
*/
|
|
266
|
-
exists(p: (right: RIGHT) => boolean): boolean {
|
|
267
|
-
return this.match({
|
|
268
|
-
right: b => p(b),
|
|
269
|
-
left: () => false
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
/** Binds the given function across `Right`.
|
|
275
|
-
*
|
|
276
|
-
* @param f The function to bind across `Right`.
|
|
277
|
-
*/
|
|
278
|
-
flatMap<RIGHT1>(f: (value: RIGHT) => Either<LEFT, RIGHT1>): Either<LEFT, RIGHT1> {
|
|
279
|
-
return this.match({
|
|
280
|
-
right: v => f(v),
|
|
281
|
-
left: () => this as unknown as Either<LEFT, RIGHT1>
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
flatMapPromise<RIGHT1>(f: (item: RIGHT) => Promise<Either<LEFT, RIGHT1>>): Promise<Either<LEFT, RIGHT1>> {
|
|
286
|
-
return this.match({
|
|
287
|
-
right: v => f(v),
|
|
288
|
-
left: () => Promise.resolve(this as unknown as Either<LEFT, RIGHT1>)
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
/** The given function is applied if this is a `Right`.
|
|
293
|
-
*
|
|
294
|
-
* ```
|
|
295
|
-
* right(12).map(x => "flower") // Result: Right("flower")
|
|
296
|
-
* left(12).map(x => "flower") // Result: Left(12)
|
|
297
|
-
* ```
|
|
298
|
-
*/
|
|
299
|
-
map<RIGHT1>(f: (value: RIGHT) => RIGHT1): Either<LEFT, RIGHT1> {
|
|
300
|
-
return this.match<Either<LEFT, RIGHT1>>({
|
|
301
|
-
right: v => right(f(v)),
|
|
302
|
-
left: () => this as unknown as Either<LEFT, RIGHT1>
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
async mapPromise<RIGHT1>(f: (v: RIGHT) => Promise<RIGHT1>): Promise<Either<LEFT, RIGHT1>> {
|
|
307
|
-
return this.match({
|
|
308
|
-
right: async v => right<RIGHT1>(await f(v)) as Either<LEFT, RIGHT1>,
|
|
309
|
-
left: () => Promise.resolve(this as unknown as Either<LEFT, RIGHT1>)
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
/** Returns `Right` with the existing value of `Right` if this is a `Right`
|
|
315
|
-
* and the given predicate `p` holds for the right value,
|
|
316
|
-
* or `Left(zero)` if this is a `Right` and the given predicate `p` does not hold for the right value,
|
|
317
|
-
* or `Left` with the existing value of `Left` if this is a `Left`.
|
|
318
|
-
*
|
|
319
|
-
* ```
|
|
320
|
-
* right(12).filterOrElse(_ => _ > 10, () => -1) // Right(12)
|
|
321
|
-
* right(7).filterOrElse(_ => _ > 10, () => -1) // Left(-1)
|
|
322
|
-
* left(7).filterOrElse(_ => false, () => -1) // Left(7)
|
|
323
|
-
* ```
|
|
324
|
-
*/
|
|
325
|
-
filterOrElse(p: (v: RIGHT) => boolean, zero: () => LEFT): Either<LEFT, RIGHT> {
|
|
326
|
-
return this.match({
|
|
327
|
-
right: (v) => p(v) ? this : left(zero()),
|
|
328
|
-
left: () => this,
|
|
329
|
-
});
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
/** Returns `Right` with the existing value of `Right` if this is a `Right`
|
|
333
|
-
* and the given predicate `p` holds for the right value,
|
|
334
|
-
* or `Left(zero)` if this is a `Right` and the given predicate `p` does not hold for the right value,
|
|
335
|
-
* or `Left` with the existing value of `Left` if this is a `Left`.
|
|
336
|
-
*
|
|
337
|
-
* ```
|
|
338
|
-
* right(12).filterOrElseValue(_ => _ > 10, -1) // Right(12)
|
|
339
|
-
* right(7).filterOrElseValue(_ => _ > 10, -1) // Left(-1)
|
|
340
|
-
* left(7).filterOrElseValue(_ => false, -1) // Left(7)
|
|
341
|
-
* ```
|
|
342
|
-
*/
|
|
343
|
-
filterOrElseValue(p: (v: RIGHT) => boolean, zero: LEFT): Either<LEFT, RIGHT> {
|
|
344
|
-
return this.match({
|
|
345
|
-
right: (v) => p(v) ? this : left(zero),
|
|
346
|
-
left: () => this,
|
|
347
|
-
});
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
/** Returns a `Collection` containing the `Right` value if
|
|
351
|
-
* it exists or an empty `Collection` if this is a `Left`.
|
|
352
|
-
*
|
|
353
|
-
* ```
|
|
354
|
-
* right(12).toCollection // Collection.of(12)
|
|
355
|
-
* left(12).toCollection // Collection.empty
|
|
356
|
-
* ```
|
|
357
|
-
*/
|
|
358
|
-
get toCollection(): Collection<RIGHT> {
|
|
359
|
-
return this.match({
|
|
360
|
-
right: v => Collection.of(v),
|
|
361
|
-
left: () => Collection.empty
|
|
362
|
-
});
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
/** Returns a `Some` containing the `Right` value
|
|
366
|
-
* if it exists or a `None` if this is a `Left`.
|
|
367
|
-
*
|
|
368
|
-
* ```
|
|
369
|
-
* right(12).toOption // Some(12)
|
|
370
|
-
* left(12).toOption // None
|
|
371
|
-
* ```
|
|
372
|
-
*/
|
|
373
|
-
get toOption(): Option<RIGHT> {
|
|
374
|
-
return this.match<Option<RIGHT>>({
|
|
375
|
-
right: v => some(v),
|
|
376
|
-
left: () => none
|
|
377
|
-
});
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
toTry(toError: (e: LEFT) => Error = toErrorConversion): TryLike<RIGHT> {
|
|
381
|
-
return this.match<TryLike<RIGHT>>({
|
|
382
|
-
right: (b) => success(b),
|
|
383
|
-
left: (e) => failure(toError(e))
|
|
384
|
-
});
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
export class Left<T> extends Either<T, any> {
|
|
392
|
-
|
|
393
|
-
constructor(private readonly error: T) {
|
|
394
|
-
super();
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
match<X>(matcher: EitherMatch<T, any, X>): X {
|
|
398
|
-
return matcher.left(this.error);
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
get isLeft(): boolean {
|
|
402
|
-
return true;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
withRight<RIGHT>(): Either<T, RIGHT> {
|
|
406
|
-
return this;
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
export class Right<T> extends Either<any, T> {
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
constructor(private readonly value: T) {
|
|
415
|
-
super();
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
match<X>(matcher: EitherMatch<any, T, X>): X {
|
|
419
|
-
return matcher.right(this.value);
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
get isLeft(): boolean {
|
|
423
|
-
return false;
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
withLeft<LEFT>(): Either<LEFT, T> {
|
|
427
|
-
return this;
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
export namespace Either {
|
|
433
|
-
export class LeftProjection<A, B> {
|
|
434
|
-
|
|
435
|
-
constructor(private readonly e: Either<A, B>) {
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
mapPromise<A1, B1 extends B>(f: (item: A) => Promise<A1>): Promise<Either<A1, B1>> {
|
|
440
|
-
return this.e.match<Promise<Either<A1, B1>>>({
|
|
441
|
-
left: async v => left<A1>(await f(v)),
|
|
442
|
-
right: () => Promise.resolve(this.e as unknown as Either<A1, B1>)
|
|
443
|
-
}) as Promise<Either<A1, B1>>;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
flatMapPromise<A1, B1 extends B>(f: (item: A) => Promise<Either<A1, B1>>): Promise<Either<A1, B1>> {
|
|
447
|
-
return this.e.match<Promise<Either<A1, B1>>>({
|
|
448
|
-
left: v => f(v),
|
|
449
|
-
right: () => Promise.resolve(this.e as unknown as Either<A1, B1>)
|
|
450
|
-
}) as Promise<Either<A1, B1>>;
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
/** Executes the given side-effecting function if this is a `Left`.
|
|
454
|
-
*
|
|
455
|
-
* ```
|
|
456
|
-
* left(12).left.foreach(x => println(x)) // prints "12"
|
|
457
|
-
* right(12).left.foreach(x => println(x)) // doesn't print
|
|
458
|
-
* ```
|
|
459
|
-
* @param f The side-effecting function to execute.
|
|
460
|
-
*/
|
|
461
|
-
foreach<U>(f: (value: A) => U): void {
|
|
462
|
-
this.e.match({
|
|
463
|
-
left: l => f(l),
|
|
464
|
-
right: () => {
|
|
465
|
-
// do nothing.
|
|
466
|
-
}
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
/** Returns the value from this `Left` or the given argument if this is a `Right`.
|
|
471
|
-
*
|
|
472
|
-
* ```
|
|
473
|
-
* left(12).left.getOrElse(17) // 12
|
|
474
|
-
* right(12).left.getOrElse(17) // 17
|
|
475
|
-
* ```
|
|
476
|
-
*/
|
|
477
|
-
getOrElse(or: () => A): A {
|
|
478
|
-
return this.e.match({
|
|
479
|
-
left: a => a,
|
|
480
|
-
right: or
|
|
481
|
-
});
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
/** Returns the value from this `Left` or the given argument if this is a `Right`.
|
|
485
|
-
*
|
|
486
|
-
* ```
|
|
487
|
-
* left(12).left.getOrElseValue(17) // 12
|
|
488
|
-
* right(12).left.getOrElseValue(17) // 17
|
|
489
|
-
* ```
|
|
490
|
-
*/
|
|
491
|
-
getOrElseValue(or: A): A {
|
|
492
|
-
return this.e.match({
|
|
493
|
-
left: a => a,
|
|
494
|
-
right: () => or
|
|
495
|
-
});
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
/** Returns `true` if `Right` or returns the result of the application of
|
|
500
|
-
* the given function to the `Left` value.
|
|
501
|
-
*
|
|
502
|
-
* ```
|
|
503
|
-
* left(12).left.forall(_ > 10) // true
|
|
504
|
-
* left(7).left.forall(_ > 10) // false
|
|
505
|
-
* right(12).left.forall(_ > 10) // true
|
|
506
|
-
* ```
|
|
507
|
-
*/
|
|
508
|
-
forall(p: (value: A) => boolean): boolean {
|
|
509
|
-
return this.e.match({
|
|
510
|
-
left: (a) => p(a),
|
|
511
|
-
right: () => true
|
|
512
|
-
});
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
/** Returns `false` if `Right` or returns the result of the application of
|
|
516
|
-
* the given function to the `Left` value.
|
|
517
|
-
*
|
|
518
|
-
* ```
|
|
519
|
-
* left(12).left.exists(_ > 10) // true
|
|
520
|
-
* left(7).left.exists(_ > 10) // false
|
|
521
|
-
* right(12).left.exists(_ > 10) // false
|
|
522
|
-
* ```
|
|
523
|
-
*/
|
|
524
|
-
exists(p: (value: A) => boolean): boolean {
|
|
525
|
-
return this.e.match({
|
|
526
|
-
left: (a) => p(a),
|
|
527
|
-
right: () => false
|
|
528
|
-
});
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
/** Binds the given function across `Left`.
|
|
533
|
-
*
|
|
534
|
-
* ```
|
|
535
|
-
* left(12).left.flatMap(x => Left("scala")) // Left("scala")
|
|
536
|
-
* right(12).left.flatMap(x => Left("scala")) // Right(12)
|
|
537
|
-
* ```
|
|
538
|
-
* @param f The function to bind across `Left`.
|
|
539
|
-
*/
|
|
540
|
-
flatMap<A1, B1 extends B>(f: (value: A) => Either<A1, B1>): Either<A1, B1> {
|
|
541
|
-
return this.e.match<Either<A1, B1>>({
|
|
542
|
-
left: (a) => f(a),
|
|
543
|
-
right: () => this.e as unknown as Either<A1, B1>
|
|
544
|
-
});
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
/** Maps the function argument through `Left`.
|
|
548
|
-
*
|
|
549
|
-
* ```
|
|
550
|
-
* left(12).left.map(_ + 2) // Left(14)
|
|
551
|
-
* right<number, number>(12).left.map(_ => _ + 2) // Right(12)
|
|
552
|
-
* ```
|
|
553
|
-
*/
|
|
554
|
-
map<A1>(f: (value: A) => A1): Either<A1, B> {
|
|
555
|
-
return this.e.match<Either<A1, B>>({
|
|
556
|
-
left: a => left(f(a)),
|
|
557
|
-
right: () => this.e as unknown as Either<A1, B>
|
|
558
|
-
});
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
/** Returns `None` if this is a `Right` or if the given predicate
|
|
563
|
-
* `p` does not hold for the left value, otherwise, returns a `Left`.
|
|
564
|
-
*
|
|
565
|
-
* ```
|
|
566
|
-
* left(12).left.filterToOption(_ => _ > 10) // Some(Left(12))
|
|
567
|
-
* left(7).left.filterToOption(_ => _ > 10) // None
|
|
568
|
-
* right(12).left.filterToOption(_ => _ > 10) // None
|
|
569
|
-
* ```
|
|
570
|
-
*/
|
|
571
|
-
filterToOption(p: (value: A) => boolean): Option<Either<A, B>> {
|
|
572
|
-
return this.e.match<Option<Either<A, B>>>({
|
|
573
|
-
left: l => p(l) ? some(this.e) : none,
|
|
574
|
-
right: () => none
|
|
575
|
-
});
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
/** Returns a `Seq` containing the `Left` value if it exists or an empty
|
|
579
|
-
* `Seq` if this is a `Right`.
|
|
580
|
-
*
|
|
581
|
-
* ```
|
|
582
|
-
* left(12).left.toSeq // Seq(12)
|
|
583
|
-
* right(12).left.toSeq // Seq()
|
|
584
|
-
* ```
|
|
585
|
-
*/
|
|
586
|
-
get toCollection(): Collection<A> {
|
|
587
|
-
return this.e.match({
|
|
588
|
-
left: l => Collection.of(l),
|
|
589
|
-
right: () => Nil
|
|
590
|
-
});
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
/** Returns a `Some` containing the `Left` value if it exists or a
|
|
594
|
-
* `None` if this is a `Right`.
|
|
595
|
-
*
|
|
596
|
-
* {{{
|
|
597
|
-
* Left(12).left.toOption // Some(12)
|
|
598
|
-
* Right(12).left.toOption // None
|
|
599
|
-
* }}}
|
|
600
|
-
*/
|
|
601
|
-
get toOption(): Option<A> {
|
|
602
|
-
return this.e.match<Option<A>>({
|
|
603
|
-
left: l => some(l),
|
|
604
|
-
right: () => none
|
|
605
|
-
});
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
export function right<T>(value: T): Right<T> {
|
|
613
|
-
return new Right(value);
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
export function left<E>(value: E): Left<E> {
|
|
617
|
-
return new Left(value);
|
|
618
|
-
}
|