t-tasks 1.2.1 → 2.0.0
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/t-tasks.d.ts +1790 -0
- package/dist/t-tasks.esm.js +752 -2
- package/dist/t-tasks.esm.js.map +1 -1
- package/dist/t-tasks.js +788 -2
- package/dist/t-tasks.js.map +1 -1
- package/package.json +12 -7
- package/src/either.ts +89 -56
- package/src/maybe.ts +83 -50
- package/src/task.ts +372 -213
- package/dist/either.d.ts +0 -626
- package/dist/index.d.ts +0 -3
- package/dist/maybe.d.ts +0 -595
- package/dist/t-tasks.modern.mjs +0 -2
- package/dist/t-tasks.modern.mjs.map +0 -1
- package/dist/t-tasks.umd.js +0 -2
- package/dist/t-tasks.umd.js.map +0 -1
- package/dist/task.d.ts +0 -489
package/src/either.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Either data type specialization representing a correct value
|
|
5
5
|
*
|
|
6
6
|
* @template R underlying value type
|
|
7
|
-
* @template L underlying error type (needed for type merging, in fact
|
|
7
|
+
* @template L underlying error type (needed for type merging, in fact always considered to be never)
|
|
8
8
|
*/
|
|
9
9
|
export interface Right<R, L> {
|
|
10
10
|
readonly right: R;
|
|
@@ -73,17 +73,22 @@ export interface Right<R, L> {
|
|
|
73
73
|
orMap<R2>(this: Either<R, L>, op: (error: L) => R2): Right<R | R2, never>;
|
|
74
74
|
|
|
75
75
|
/**
|
|
76
|
-
* Either pattern matching
|
|
76
|
+
* Either pattern matching extractor function
|
|
77
77
|
*
|
|
78
|
-
* Applied to 'right value' returns
|
|
79
|
-
* Applied to 'left error' returns
|
|
78
|
+
* Applied to 'right value' returns op.right(value)
|
|
79
|
+
* Applied to 'left error' returns op.left(error)
|
|
80
80
|
*
|
|
81
|
-
* @template R2 right
|
|
82
|
-
* @template R3 left
|
|
83
|
-
* @param op.right
|
|
84
|
-
* @param op.left
|
|
85
|
-
* @returns
|
|
81
|
+
* @template R2 right extractor function's return type
|
|
82
|
+
* @template R3 left extractor function's return type
|
|
83
|
+
* @param op.right extractor to be invoked with underlying value in case of 'right'
|
|
84
|
+
* @param op.left extractor to be invoked with underlying error in case of 'left'
|
|
85
|
+
* @returns op.right(value) or op.left(error)
|
|
86
86
|
*/
|
|
87
|
+
// Right case
|
|
88
|
+
match<R2, R3 = R2>(this: Right<R, L>, op: { right: (value: R) => R2; left: (error: L) => R3 }): R2;
|
|
89
|
+
// General case
|
|
90
|
+
match<R2, R3 = R2>(this: Either<R, L>, op: { right: (value: R) => R2; left: (error: L) => R3 }): R2 | R3;
|
|
91
|
+
|
|
87
92
|
// Right case
|
|
88
93
|
matchMap<R2, R3 = R2>(this: Right<R, L>, op: { right: (value: R) => R2; left: (error: L) => R3 }): Right<R2, never>;
|
|
89
94
|
// General case
|
|
@@ -117,7 +122,7 @@ export interface Right<R, L> {
|
|
|
117
122
|
*
|
|
118
123
|
* @template R2 transformer function result's underlying value type
|
|
119
124
|
* @template L2 transformer function result's underlying error type
|
|
120
|
-
* @param op transformer to be invoked with underlying
|
|
125
|
+
* @param op transformer to be invoked with underlying error
|
|
121
126
|
* @returns 'right value' or 'op(error)'
|
|
122
127
|
*/
|
|
123
128
|
// Right cases
|
|
@@ -193,13 +198,13 @@ export interface Right<R, L> {
|
|
|
193
198
|
isLeft(): this is Left<R, L>;
|
|
194
199
|
|
|
195
200
|
/**
|
|
196
|
-
* Wrap
|
|
201
|
+
* Wrap Either to singleton generator
|
|
197
202
|
*
|
|
198
|
-
*
|
|
203
|
+
* Useful in order to avoid ambiguous yield types
|
|
199
204
|
*
|
|
200
|
-
* @returns generator of
|
|
205
|
+
* @returns generator of Either wrapping this
|
|
201
206
|
*/
|
|
202
|
-
|
|
207
|
+
generator: EitherGeneratorFunction<[], R, Right<R, L>, R>
|
|
203
208
|
}
|
|
204
209
|
|
|
205
210
|
/**
|
|
@@ -207,7 +212,7 @@ export interface Right<R, L> {
|
|
|
207
212
|
*
|
|
208
213
|
* Either data type specialization representing an erroneous value
|
|
209
214
|
*
|
|
210
|
-
* @
|
|
215
|
+
* @template R underlying value type (needed for type merging, in fact always considered to be never)
|
|
211
216
|
* @template L underlying error type
|
|
212
217
|
*/
|
|
213
218
|
export interface Left<R, L> {
|
|
@@ -230,7 +235,7 @@ export interface Left<R, L> {
|
|
|
230
235
|
* Applied to 'right value' returns self without invoking callback
|
|
231
236
|
* Applied to 'left error' returns self invoking op(error) in process
|
|
232
237
|
*
|
|
233
|
-
* @param op function to be invoked with underlying
|
|
238
|
+
* @param op function to be invoked with underlying error
|
|
234
239
|
* @returns self
|
|
235
240
|
*/
|
|
236
241
|
orTap(op: (error: L) => void): this;
|
|
@@ -277,17 +282,22 @@ export interface Left<R, L> {
|
|
|
277
282
|
orMap<R2>(this: Either<R, L>, op: (error: L) => R2): Right<R | R2, never>;
|
|
278
283
|
|
|
279
284
|
/**
|
|
280
|
-
* Either pattern matching
|
|
285
|
+
* Either pattern matching extractor function
|
|
281
286
|
*
|
|
282
|
-
* Applied to 'right value' returns
|
|
283
|
-
* Applied to 'left error' returns
|
|
287
|
+
* Applied to 'right value' returns op.right(value)
|
|
288
|
+
* Applied to 'left error' returns op.left(error)
|
|
284
289
|
*
|
|
285
|
-
* @template R2 right
|
|
286
|
-
* @template R3 left
|
|
287
|
-
* @param op.right
|
|
288
|
-
* @param op.left
|
|
289
|
-
* @returns
|
|
290
|
+
* @template R2 right extractor function's return type
|
|
291
|
+
* @template R3 left extractor function's return type
|
|
292
|
+
* @param op.right extractor to be invoked with underlying value in case of 'right'
|
|
293
|
+
* @param op.left extractor to be invoked with underlying error in case of 'left'
|
|
294
|
+
* @returns op.right(value) or op.left(error)
|
|
290
295
|
*/
|
|
296
|
+
// Left case
|
|
297
|
+
match<R2, R3 = R2>(this: Left<R, L>, op: { right: (value: R) => R2; left: (error: L) => R3 }): R3;
|
|
298
|
+
// General case
|
|
299
|
+
match<R2, R3 = R2>(this: Either<R, L>, op: { right: (value: R) => R2; left: (error: L) => R3 }): R2 | R3;
|
|
300
|
+
|
|
291
301
|
// Left case
|
|
292
302
|
matchMap<R2, R3 = R2>(this: Left<R, L>, op: { right: (value: R) => R2; left: (error: L) => R3 }): Right<R3, never>;
|
|
293
303
|
// General case
|
|
@@ -304,7 +314,7 @@ export interface Left<R, L> {
|
|
|
304
314
|
* @param op transformer to be invoked with underlying value
|
|
305
315
|
* @returns 'op(value)' or 'left error'
|
|
306
316
|
*/
|
|
307
|
-
//
|
|
317
|
+
// Left cases
|
|
308
318
|
chain<R2, L2>(this: Left<R, L>, op: (value: R) => Right<R2, L2>): Left<never, L>;
|
|
309
319
|
chain<R2, L2>(this: Left<R, L>, op: (value: R) => Left<R2, L2>): Left<never, L>;
|
|
310
320
|
chain<R2, L2>(this: Left<R, L>, op: (value: R) => Either<R2, L2>): Left<never, L>;
|
|
@@ -321,7 +331,7 @@ export interface Left<R, L> {
|
|
|
321
331
|
*
|
|
322
332
|
* @template R2 transformer function result's underlying value type
|
|
323
333
|
* @template L2 transformer function result's underlying error type
|
|
324
|
-
* @param op transformer to be invoked with underlying
|
|
334
|
+
* @param op transformer to be invoked with underlying error
|
|
325
335
|
* @returns 'right value' or 'op(error)'
|
|
326
336
|
*/
|
|
327
337
|
// Left cases
|
|
@@ -397,19 +407,19 @@ export interface Left<R, L> {
|
|
|
397
407
|
isLeft(): this is Left<R, L>;
|
|
398
408
|
|
|
399
409
|
/**
|
|
400
|
-
* Wrap
|
|
410
|
+
* Wrap Either to singleton generator
|
|
401
411
|
*
|
|
402
|
-
*
|
|
412
|
+
* Useful in order to avoid ambiguous yield types
|
|
403
413
|
*
|
|
404
|
-
* @returns generator of
|
|
414
|
+
* @returns generator of Either wrapping this
|
|
405
415
|
*/
|
|
406
|
-
|
|
416
|
+
generator: EitherGeneratorFunction<[], R, Left<R, L>, R>
|
|
407
417
|
}
|
|
408
418
|
|
|
409
419
|
/**
|
|
410
420
|
* Either data type: either Right value of type R or Left value of type L
|
|
411
421
|
*
|
|
412
|
-
* As per classic Either monad implementation can
|
|
422
|
+
* As per classic Either monad implementation can either contain a right (correct) value or a left (erroneous) value
|
|
413
423
|
* Used throughout the library to represent the result of failable operations, namely failed tasks
|
|
414
424
|
*
|
|
415
425
|
* @template R underlying value type
|
|
@@ -421,7 +431,7 @@ export namespace Right {
|
|
|
421
431
|
/**
|
|
422
432
|
* Standalone Right value extractor
|
|
423
433
|
*
|
|
424
|
-
*
|
|
434
|
+
* Useful for passing as a function to collection transformers
|
|
425
435
|
*
|
|
426
436
|
* @template R underlying value type
|
|
427
437
|
* @template L underlying error type
|
|
@@ -437,7 +447,7 @@ export namespace Left {
|
|
|
437
447
|
/**
|
|
438
448
|
* Standalone Left error extractor
|
|
439
449
|
*
|
|
440
|
-
*
|
|
450
|
+
* Useful for passing as a function to collection transformers
|
|
441
451
|
*
|
|
442
452
|
* @template R underlying value type
|
|
443
453
|
* @template L underlying error type
|
|
@@ -508,10 +518,30 @@ export namespace Either {
|
|
|
508
518
|
return Either.fromOptional(value, error).chain((v) => (v !== null ? Either.right(value) : Either.left(error)));
|
|
509
519
|
}
|
|
510
520
|
|
|
521
|
+
/**
|
|
522
|
+
* Standalone Either value extractor
|
|
523
|
+
*
|
|
524
|
+
* Applied to 'right value' returns underlying value without using fallback
|
|
525
|
+
* Applied to 'left error' returns fallback
|
|
526
|
+
*
|
|
527
|
+
* @template R underlying value type
|
|
528
|
+
* @template L underlying error type
|
|
529
|
+
* @template R2 fallback value type
|
|
530
|
+
* @param either Either instance
|
|
531
|
+
* @param fallback value to be returned in case of 'left error'
|
|
532
|
+
* @returns underlying value or fallback
|
|
533
|
+
*/
|
|
534
|
+
export function fromEither<R, L>(either: Right<R, L>, fallback: unknown): R;
|
|
535
|
+
export function fromEither<R, L, R2>(either: Left<R, L>, fallback: R2): R2;
|
|
536
|
+
export function fromEither<R, L, R2>(either: Either<R, L>, fallback: R2): R | R2;
|
|
537
|
+
export function fromEither<R, L, R2>(either: Either<R, L>, fallback: R2) {
|
|
538
|
+
return either.match({ right: (value) => value, left: () => fallback });
|
|
539
|
+
}
|
|
540
|
+
|
|
511
541
|
/**
|
|
512
542
|
* Standalone type guard for 'right'
|
|
513
543
|
*
|
|
514
|
-
*
|
|
544
|
+
* Useful for passing as a predicate to collection transformers
|
|
515
545
|
*
|
|
516
546
|
* @template R underlying value type
|
|
517
547
|
* @param either Either instance
|
|
@@ -524,7 +554,7 @@ export namespace Either {
|
|
|
524
554
|
/**
|
|
525
555
|
* Standalone type guard for 'left'
|
|
526
556
|
*
|
|
527
|
-
*
|
|
557
|
+
* Useful for passing as a predicate to collection transformers
|
|
528
558
|
*
|
|
529
559
|
* @template R underlying value type
|
|
530
560
|
* @param either Either instance
|
|
@@ -577,30 +607,27 @@ export namespace Either {
|
|
|
577
607
|
/**
|
|
578
608
|
* Create compound Either from generator function
|
|
579
609
|
*
|
|
580
|
-
* Applying yield to
|
|
581
|
-
* However the
|
|
610
|
+
* Applying yield to an Either within the generator function unwraps the Either and returns underlying value in case of success
|
|
611
|
+
* However the convenient option for typescript is to use ```yield* either.generator()``` as otherwise one may have to deal with union types
|
|
582
612
|
*
|
|
583
|
-
* @template TT yielded
|
|
613
|
+
* @template TT yielded Either type
|
|
584
614
|
* @template R returned underlying type
|
|
585
|
-
* @param
|
|
586
|
-
* @returns
|
|
587
|
-
* ```
|
|
615
|
+
* @param eitherGeneratorFunction Either generator function
|
|
616
|
+
* @returns Right wrapping the result of generator function or Left
|
|
588
617
|
*/
|
|
589
618
|
export function generate<T, TT extends Either<T, any>, R>(eitherGeneratorFunction: EitherGeneratorFunction<[], T, TT, R>): Either<R, any> {
|
|
590
619
|
const generator = eitherGeneratorFunction();
|
|
620
|
+
let next = generator.next();
|
|
591
621
|
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
Either.
|
|
595
|
-
|
|
596
|
-
next.value.matchChain<R, any>({
|
|
597
|
-
right: (value) => sequentor(generator.next(value)),
|
|
598
|
-
left: Either.left,
|
|
599
|
-
})
|
|
600
|
-
);
|
|
601
|
-
};
|
|
622
|
+
while (!next.done) {
|
|
623
|
+
if (next.value.isLeft()) {
|
|
624
|
+
return Either.left(next.value.left);
|
|
625
|
+
}
|
|
602
626
|
|
|
603
|
-
|
|
627
|
+
next = generator.next(next.value.right);
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
return Either.right(next.value);
|
|
604
631
|
}
|
|
605
632
|
}
|
|
606
633
|
|
|
@@ -625,7 +652,7 @@ class RightClass<R> implements Right<R, never> {
|
|
|
625
652
|
orMap() {
|
|
626
653
|
return this;
|
|
627
654
|
}
|
|
628
|
-
chain<
|
|
655
|
+
chain<RR extends Either<unknown, unknown>>(op: (value: R) => RR) {
|
|
629
656
|
return op(this.right);
|
|
630
657
|
}
|
|
631
658
|
orChain() {
|
|
@@ -637,13 +664,16 @@ class RightClass<R> implements Right<R, never> {
|
|
|
637
664
|
isLeft(): this is Left<R, never> {
|
|
638
665
|
return false;
|
|
639
666
|
}
|
|
667
|
+
match<R2>(op: { right: (value: R) => R2 }) {
|
|
668
|
+
return op.right(this.right);
|
|
669
|
+
}
|
|
640
670
|
matchTap(op: { right: (value: R) => void }) {
|
|
641
671
|
return this.tap(op.right);
|
|
642
672
|
}
|
|
643
673
|
matchMap<R2>(op: { right: (value: R) => R2 }) {
|
|
644
674
|
return this.map(op.right);
|
|
645
675
|
}
|
|
646
|
-
matchChain<
|
|
676
|
+
matchChain<RR extends Either<unknown, unknown>>(op: { right: (value: R) => RR }) {
|
|
647
677
|
return this.chain(op.right);
|
|
648
678
|
}
|
|
649
679
|
generator() {
|
|
@@ -673,7 +703,7 @@ class LeftClass<L> implements Left<never, L> {
|
|
|
673
703
|
chain() {
|
|
674
704
|
return this;
|
|
675
705
|
}
|
|
676
|
-
orChain<
|
|
706
|
+
orChain<RR extends Either<unknown, unknown>>(op: (error: L) => RR) {
|
|
677
707
|
return op(this.left);
|
|
678
708
|
}
|
|
679
709
|
isRight(): this is Right<never, L> {
|
|
@@ -682,13 +712,16 @@ class LeftClass<L> implements Left<never, L> {
|
|
|
682
712
|
isLeft(): this is Left<never, L> {
|
|
683
713
|
return true;
|
|
684
714
|
}
|
|
715
|
+
match<R2>(op: { left: (error: L) => R2 }) {
|
|
716
|
+
return op.left(this.left);
|
|
717
|
+
}
|
|
685
718
|
matchTap(op: { left: (error: L) => void }) {
|
|
686
719
|
return this.orTap(op.left);
|
|
687
720
|
}
|
|
688
721
|
matchMap<R2>(op: { left: (error: L) => R2 }) {
|
|
689
722
|
return this.orMap(op.left);
|
|
690
723
|
}
|
|
691
|
-
matchChain<
|
|
724
|
+
matchChain<RR extends Either<unknown, unknown>>(op: { left: (error: L) => RR }) {
|
|
692
725
|
return this.orChain(op.left);
|
|
693
726
|
}
|
|
694
727
|
generator() {
|
package/src/maybe.ts
CHANGED
|
@@ -31,7 +31,7 @@ export interface Just<R> {
|
|
|
31
31
|
orTap(op: () => void): this;
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
|
-
* Maybe
|
|
34
|
+
* Maybe pattern matching peeker function
|
|
35
35
|
*
|
|
36
36
|
* Applied to 'just value' returns self invoking op.just(value) in process
|
|
37
37
|
* Applied to 'nothing' returns self invoking op.nothing() in process
|
|
@@ -72,22 +72,28 @@ export interface Just<R> {
|
|
|
72
72
|
orMap<R2>(this: Maybe<R>, op: () => R2): Just<R | R2>;
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
|
-
* Maybe
|
|
75
|
+
* Maybe pattern matching extractor function
|
|
76
76
|
*
|
|
77
|
-
* Applied to 'just value' returns
|
|
78
|
-
* Applied to 'nothing' returns
|
|
77
|
+
* Applied to 'just value' returns op.just(value)
|
|
78
|
+
* Applied to 'nothing' returns op.nothing()
|
|
79
79
|
*
|
|
80
|
-
* @template R2 just
|
|
81
|
-
* @template R3 nothing
|
|
82
|
-
* @param op.just
|
|
83
|
-
* @param op.nothing
|
|
84
|
-
* @returns
|
|
80
|
+
* @template R2 just extractor function's return type
|
|
81
|
+
* @template R3 nothing extractor function's return type
|
|
82
|
+
* @param op.just extractor to be invoked with underlying value in case of just
|
|
83
|
+
* @param op.nothing extractor to be invoked in case of nothing
|
|
84
|
+
* @returns op.just(value) or op.nothing()
|
|
85
85
|
*/
|
|
86
86
|
// Just cases
|
|
87
|
+
match<R2, R3 = R2>(this: Just<R>, op: { just: (value: R) => R2; nothing: () => R3 }): R2;
|
|
88
|
+
// General case
|
|
89
|
+
match<R2, R3 = R2>(this: Maybe<R>, op: { just: (value: R) => R2; nothing: () => R3 }): R2 | R3;
|
|
90
|
+
|
|
91
|
+
// Nothing cases
|
|
87
92
|
matchMap<R2, R3 = R2>(this: Just<R>, op: { just: (value: R) => R2; nothing: () => R3 }): Just<R2>;
|
|
88
93
|
// General case
|
|
89
94
|
matchMap<R2, R3 = R2>(this: Maybe<R>, op: { just: (value: R) => R2; nothing: () => R3 }): Just<R2 | R3>;
|
|
90
95
|
|
|
96
|
+
|
|
91
97
|
/**
|
|
92
98
|
* Maybe composition function
|
|
93
99
|
*
|
|
@@ -110,7 +116,7 @@ export interface Just<R> {
|
|
|
110
116
|
/**
|
|
111
117
|
* Maybe fallback composition function
|
|
112
118
|
*
|
|
113
|
-
* Applied to 'just value' returns self
|
|
119
|
+
* Applied to 'just value' returns self without invoking composition function
|
|
114
120
|
* Applied to 'nothing' returns op()
|
|
115
121
|
*
|
|
116
122
|
* @template R2 transformer function result's underlying type
|
|
@@ -127,7 +133,7 @@ export interface Just<R> {
|
|
|
127
133
|
orChain<R2>(this: Maybe<R>, op: () => Maybe<R2>): Maybe<R | R2>;
|
|
128
134
|
|
|
129
135
|
/**
|
|
130
|
-
* Maybe
|
|
136
|
+
* Maybe pattern matching composition function
|
|
131
137
|
*
|
|
132
138
|
* Applied to 'just value' returns 'op.just(value)'
|
|
133
139
|
* Applied to 'nothing' returns op.nothing()
|
|
@@ -180,7 +186,7 @@ export interface Just<R> {
|
|
|
180
186
|
*
|
|
181
187
|
* @example
|
|
182
188
|
* ```typescript
|
|
183
|
-
* if (maybe.
|
|
189
|
+
* if (maybe.isNothing()) {
|
|
184
190
|
* console.log('nothing');
|
|
185
191
|
* }
|
|
186
192
|
* ```
|
|
@@ -190,7 +196,7 @@ export interface Just<R> {
|
|
|
190
196
|
/**
|
|
191
197
|
* Wrap Maybe to singleton generator
|
|
192
198
|
*
|
|
193
|
-
*
|
|
199
|
+
* Useful in order to avoid ambiguous yield types
|
|
194
200
|
*
|
|
195
201
|
* @returns generator of Maybe wrapping this
|
|
196
202
|
*/
|
|
@@ -200,7 +206,7 @@ export interface Just<R> {
|
|
|
200
206
|
/**
|
|
201
207
|
* Absolutely Nothing
|
|
202
208
|
*
|
|
203
|
-
* Maybe data type
|
|
209
|
+
* Maybe data type specialization representing an absence of any value
|
|
204
210
|
*/
|
|
205
211
|
export interface Nothing<R> {
|
|
206
212
|
/**
|
|
@@ -226,7 +232,7 @@ export interface Nothing<R> {
|
|
|
226
232
|
orTap(op: () => void): this;
|
|
227
233
|
|
|
228
234
|
/**
|
|
229
|
-
* Maybe
|
|
235
|
+
* Maybe pattern matching peeker function
|
|
230
236
|
*
|
|
231
237
|
* Applied to 'just value' returns self invoking op.just(value) in process
|
|
232
238
|
* Applied to 'nothing' returns self invoking op.nothing() in process
|
|
@@ -267,20 +273,25 @@ export interface Nothing<R> {
|
|
|
267
273
|
orMap<R2>(this: Maybe<R>, op: () => R2): Just<R | R2>;
|
|
268
274
|
|
|
269
275
|
/**
|
|
270
|
-
* Maybe
|
|
276
|
+
* Maybe pattern matching extractor function
|
|
271
277
|
*
|
|
272
|
-
* Applied to 'just value' returns
|
|
273
|
-
* Applied to 'nothing' returns
|
|
278
|
+
* Applied to 'just value' returns op.just(value)
|
|
279
|
+
* Applied to 'nothing' returns op.nothing()
|
|
274
280
|
*
|
|
275
|
-
* @template R2 just
|
|
276
|
-
* @template R3 nothing
|
|
277
|
-
* @param op.just
|
|
278
|
-
* @param op.nothing
|
|
279
|
-
* @returns
|
|
281
|
+
* @template R2 just extractor function's return type
|
|
282
|
+
* @template R3 nothing extractor function's return type
|
|
283
|
+
* @param op.just extractor to be invoked with underlying value in case of just
|
|
284
|
+
* @param op.nothing extractor to be invoked in case of nothing
|
|
285
|
+
* @returns op.just(value) or op.nothing()
|
|
280
286
|
*/
|
|
281
287
|
// Nothing cases
|
|
288
|
+
match<R2, R3 = R2>(this: Nothing<R>, op: { just: (value: R) => R2; nothing: () => R3 }): R3;
|
|
289
|
+
// General case
|
|
290
|
+
match<R2, R3 = R2>(this: Maybe<R>, op: { just: (value: R) => R2; nothing: () => R3 }): R2 | R3;
|
|
291
|
+
|
|
292
|
+
// Just cases
|
|
282
293
|
matchMap<R2, R3 = R2>(this: Nothing<R>, op: { just: (value: R) => R2; nothing: () => R3 }): Just<R3>;
|
|
283
|
-
// General
|
|
294
|
+
// General case
|
|
284
295
|
matchMap<R2, R3 = R2>(this: Maybe<R>, op: { just: (value: R) => R2; nothing: () => R3 }): Just<R2 | R3>;
|
|
285
296
|
|
|
286
297
|
/**
|
|
@@ -305,7 +316,7 @@ export interface Nothing<R> {
|
|
|
305
316
|
/**
|
|
306
317
|
* Maybe fallback composition function
|
|
307
318
|
*
|
|
308
|
-
* Applied to 'just value' returns self
|
|
319
|
+
* Applied to 'just value' returns self without invoking composition function
|
|
309
320
|
* Applied to 'nothing' returns op()
|
|
310
321
|
*
|
|
311
322
|
* @template R2 transformer function result's underlying type
|
|
@@ -322,7 +333,7 @@ export interface Nothing<R> {
|
|
|
322
333
|
orChain<R2>(this: Maybe<R>, op: () => Maybe<R2>): Maybe<R | R2>;
|
|
323
334
|
|
|
324
335
|
/**
|
|
325
|
-
* Maybe
|
|
336
|
+
* Maybe pattern matching composition function
|
|
326
337
|
*
|
|
327
338
|
* Applied to 'just value' returns 'op.just(value)'
|
|
328
339
|
* Applied to 'nothing' returns op.nothing()
|
|
@@ -375,7 +386,7 @@ export interface Nothing<R> {
|
|
|
375
386
|
*
|
|
376
387
|
* @example
|
|
377
388
|
* ```typescript
|
|
378
|
-
* if (maybe.
|
|
389
|
+
* if (maybe.isNothing()) {
|
|
379
390
|
* console.log('nothing');
|
|
380
391
|
* }
|
|
381
392
|
* ```
|
|
@@ -385,7 +396,7 @@ export interface Nothing<R> {
|
|
|
385
396
|
/**
|
|
386
397
|
* Wrap Maybe to singleton generator
|
|
387
398
|
*
|
|
388
|
-
*
|
|
399
|
+
* Useful in order to avoid ambiguous yield types
|
|
389
400
|
*
|
|
390
401
|
* @returns generator of Maybe wrapping this
|
|
391
402
|
*/
|
|
@@ -393,9 +404,9 @@ export interface Nothing<R> {
|
|
|
393
404
|
}
|
|
394
405
|
|
|
395
406
|
/**
|
|
396
|
-
*
|
|
407
|
+
* Generic Maybe monad interface
|
|
397
408
|
*
|
|
398
|
-
* As per classic Maybe monad implementation can
|
|
409
|
+
* As per classic Maybe monad implementation can either contain just a value or contain nothing
|
|
399
410
|
* Used throughout the library to represent optional return type, specifically return type of cancelled tasks
|
|
400
411
|
*
|
|
401
412
|
* @template R underlying value
|
|
@@ -406,7 +417,7 @@ export namespace Just {
|
|
|
406
417
|
/**
|
|
407
418
|
* Standalone Just value extractor
|
|
408
419
|
*
|
|
409
|
-
*
|
|
420
|
+
* Useful for passing as a function to collection transformers
|
|
410
421
|
*
|
|
411
422
|
* @template R underlying value type
|
|
412
423
|
* @param just Just instance
|
|
@@ -439,8 +450,8 @@ export namespace Maybe {
|
|
|
439
450
|
*
|
|
440
451
|
* @returns 'nothing'
|
|
441
452
|
*/
|
|
442
|
-
export function nothing(): Nothing<
|
|
443
|
-
return staticNothing
|
|
453
|
+
export function nothing<R = never>(): Nothing<R> {
|
|
454
|
+
return staticNothing as Nothing<R>;
|
|
444
455
|
}
|
|
445
456
|
|
|
446
457
|
/**
|
|
@@ -474,10 +485,29 @@ export namespace Maybe {
|
|
|
474
485
|
return Maybe.fromOptional(value).chain((v) => (v !== null ? Maybe.just(v) : Maybe.nothing()));
|
|
475
486
|
}
|
|
476
487
|
|
|
488
|
+
/**
|
|
489
|
+
* Standalone Maybe value extractor
|
|
490
|
+
*
|
|
491
|
+
* Applied to 'just value' returns underlying value without using fallback
|
|
492
|
+
* Applied to 'nothing' returns fallback
|
|
493
|
+
*
|
|
494
|
+
* @template R underlying value type
|
|
495
|
+
* @template R2 fallback value type
|
|
496
|
+
* @param maybe Maybe instance
|
|
497
|
+
* @param fallback value to be returned in case of 'nothing'
|
|
498
|
+
* @returns underlying value or fallback
|
|
499
|
+
*/
|
|
500
|
+
export function fromMaybe<R>(maybe: Just<R>, fallback: unknown): R;
|
|
501
|
+
export function fromMaybe<R, R2>(maybe: Nothing<R>, fallback: R2): R2;
|
|
502
|
+
export function fromMaybe<R, R2>(maybe: Maybe<R>, fallback: R2): R | R2;
|
|
503
|
+
export function fromMaybe<R, R2>(maybe: Maybe<R>, fallback: R2) {
|
|
504
|
+
return maybe.match({ just: (value) => value, nothing: () => fallback });
|
|
505
|
+
}
|
|
506
|
+
|
|
477
507
|
/**
|
|
478
508
|
* Standalone type guard for 'just'
|
|
479
509
|
*
|
|
480
|
-
*
|
|
510
|
+
* Useful for passing as a predicate to collection transformers
|
|
481
511
|
*
|
|
482
512
|
* @template R underlying value type
|
|
483
513
|
* @param maybe Maybe instance
|
|
@@ -490,13 +520,13 @@ export namespace Maybe {
|
|
|
490
520
|
/**
|
|
491
521
|
* Standalone type guard for 'nothing'
|
|
492
522
|
*
|
|
493
|
-
*
|
|
523
|
+
* Useful for passing as a predicate to collection transformers
|
|
494
524
|
*
|
|
495
525
|
* @template R underlying value type
|
|
496
526
|
* @param maybe Maybe instance
|
|
497
527
|
* @returns 'true' in case wrapped value is 'nothing' (and resolves argument type to be 'nothing')
|
|
498
528
|
*/
|
|
499
|
-
export function isNothing<R>(maybe: Maybe<R>): maybe is Nothing<
|
|
529
|
+
export function isNothing<R>(maybe: Maybe<R>): maybe is Nothing<R> {
|
|
500
530
|
return maybe.isNothing();
|
|
501
531
|
}
|
|
502
532
|
|
|
@@ -514,7 +544,7 @@ export namespace Maybe {
|
|
|
514
544
|
* Standalone list predicate
|
|
515
545
|
*
|
|
516
546
|
* @param maybes a list of Maybe
|
|
517
|
-
* @returns true in case
|
|
547
|
+
* @returns true in case at least one list element is Just
|
|
518
548
|
*/
|
|
519
549
|
export function someJust<R>(maybes: Maybe<R>[]): boolean {
|
|
520
550
|
return maybes.some(Maybe.isJust);
|
|
@@ -544,29 +574,26 @@ export namespace Maybe {
|
|
|
544
574
|
* Create compound Maybe from generator function
|
|
545
575
|
*
|
|
546
576
|
* Applying yield to a Maybe within the generator function unwraps the Maybe and returns underlying value in case of success
|
|
547
|
-
* However the
|
|
577
|
+
* However the convenient option for typescript is to use ```yield* maybe.generator()``` as otherwise one may have to deal with union types
|
|
548
578
|
*
|
|
549
579
|
* @template TT yielded Maybe type
|
|
550
580
|
* @template R returned underlying type
|
|
551
581
|
* @param maybeGeneratorFunction Maybe generator function
|
|
552
582
|
* @returns Just wrapping the result of generator function or Nothing
|
|
553
|
-
* ```
|
|
554
583
|
*/
|
|
555
584
|
export function generate<T, TT extends Maybe<T>, R>(maybeGeneratorFunction: MaybeGeneratorFunction<[], T, TT, R>): Maybe<R> {
|
|
556
585
|
const generator = maybeGeneratorFunction();
|
|
586
|
+
let next = generator.next();
|
|
557
587
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
Maybe.
|
|
561
|
-
|
|
562
|
-
next.value.matchChain<R>({
|
|
563
|
-
just: (value) => sequentor(generator.next(value)),
|
|
564
|
-
nothing: Maybe.nothing,
|
|
565
|
-
})
|
|
566
|
-
);
|
|
567
|
-
};
|
|
588
|
+
while (!next.done) {
|
|
589
|
+
if (next.value.isNothing()) {
|
|
590
|
+
return Maybe.nothing();
|
|
591
|
+
}
|
|
568
592
|
|
|
569
|
-
|
|
593
|
+
next = generator.next(next.value.just);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
return Maybe.just(next.value);
|
|
570
597
|
}
|
|
571
598
|
}
|
|
572
599
|
|
|
@@ -603,6 +630,9 @@ class JustClass<R> implements Just<R> {
|
|
|
603
630
|
isNothing(): this is Nothing<R> {
|
|
604
631
|
return false;
|
|
605
632
|
}
|
|
633
|
+
match<R2>(op: { just: (value: R) => R2 }) {
|
|
634
|
+
return op.just(this.just);
|
|
635
|
+
}
|
|
606
636
|
matchTap(op: { just: (value: R) => void }) {
|
|
607
637
|
return this.tap(op.just);
|
|
608
638
|
}
|
|
@@ -646,6 +676,9 @@ class NothingClass implements Nothing<never> {
|
|
|
646
676
|
isNothing(): this is Nothing<never> {
|
|
647
677
|
return true;
|
|
648
678
|
}
|
|
679
|
+
match<R2>(op: { nothing: () => R2 }) {
|
|
680
|
+
return op.nothing();
|
|
681
|
+
}
|
|
649
682
|
matchTap(op: { nothing: () => void }) {
|
|
650
683
|
return this.orTap(op.nothing);
|
|
651
684
|
}
|