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/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 alwas considered to be never)
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 transformer function
76
+ * Either pattern matching extractor function
77
77
  *
78
- * Applied to 'right value' returns 'right op.right(value)'
79
- * Applied to 'left error' returns 'right op.left(error)'
78
+ * Applied to 'right value' returns op.right(value)
79
+ * Applied to 'left error' returns op.left(error)
80
80
  *
81
- * @template R2 right transformer function's return type
82
- * @template R3 left transformer function's return type
83
- * @param op.right transformer to be invoked with underlying value in case of 'right'
84
- * @param op.left transformer to be invoked with underlying error in case of 'left'
85
- * @returns 'right op.right(value)' or 'right op.left(error)'
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 value
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 Maybe to singleton generator
201
+ * Wrap Either to singleton generator
197
202
  *
198
- * Userful in order to avoid ambiguous yied types
203
+ * Useful in order to avoid ambiguous yield types
199
204
  *
200
- * @returns generator of Maybe wrapping this
205
+ * @returns generator of Either wrapping this
201
206
  */
202
- generator: EitherGeneratorFunction<[], R, Right<R, L>, R>
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
- * @remplate R underlying value type (needed for type merging, in fact alwas considered to be never)
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 value
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 transformer function
285
+ * Either pattern matching extractor function
281
286
  *
282
- * Applied to 'right value' returns 'right op.right(value)'
283
- * Applied to 'left error' returns 'right op.left(error)'
287
+ * Applied to 'right value' returns op.right(value)
288
+ * Applied to 'left error' returns op.left(error)
284
289
  *
285
- * @template R2 right transformer function's return type
286
- * @template R3 left transformer function's return type
287
- * @param op.right transformer to be invoked with underlying value in case of 'right'
288
- * @param op.left transformer to be invoked with underlying error in case of 'left'
289
- * @returns 'right op.right(value)' or 'right op.left(error)'
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
- // Right cases
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 value
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 Maybe to singleton generator
410
+ * Wrap Either to singleton generator
401
411
  *
402
- * Userful in order to avoid ambiguous yied types
412
+ * Useful in order to avoid ambiguous yield types
403
413
  *
404
- * @returns generator of Maybe wrapping this
414
+ * @returns generator of Either wrapping this
405
415
  */
406
- generator: EitherGeneratorFunction<[], R, Left<R, L>, R>
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 eithr contain a right (correct) value or a left (erroneous) value
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
- * Userful for passing as a function to collection transformers
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
- * Userful for passing as a function to collection transformers
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
- * Userful for passing as a predicate to collection transformers
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
- * Userful for passing as a predicate to collection transformers
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 a Maybe within the generator function unwraps the Maybe and returns underlying value in case of success
581
- * However the convinient option for typescript is to use ```yield* maybe.generator()``` as othervise one may have to deal with union types
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 Maybe type
613
+ * @template TT yielded Either type
584
614
  * @template R returned underlying type
585
- * @param maybeGeneratorFunction Maybe generator function
586
- * @returns Just wrapping the result of generator function or Nothing
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
- const sequentor = (next: IteratorResult<TT, R>): Either<R, any> => {
593
- return next.done ? (
594
- Either.right(next.value)
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
- return Either.right(undefined).chain(() => sequentor(generator.next()));
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<TT extends Either<unknown, unknown>>(op: (value: R) => TT) {
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<TT extends Either<unknown, unknown>>(op: { right: (value: R) => TT }) {
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<TT extends Either<unknown, unknown>>(op: (error: L) => TT) {
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<TT extends Either<unknown, unknown>>(op: { left: (error: L) => TT }) {
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 patter matching peeker function
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 patter matching transformer function
75
+ * Maybe pattern matching extractor function
76
76
  *
77
- * Applied to 'just value' returns 'just op.just(value)'
78
- * Applied to 'nothing' returns 'just op.nothing()'
77
+ * Applied to 'just value' returns op.just(value)
78
+ * Applied to 'nothing' returns op.nothing()
79
79
  *
80
- * @template R2 just transformer function's return type
81
- * @template R3 nothing transformer function's return type
82
- * @param op.just transformer to be invoked with underlying value in case of just
83
- * @param op.nothing transformer to be invoked in case of nothing
84
- * @returns 'just op.just(value)' or 'just op.nothing()'
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 witjout invoking composition function
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 patter matching composition function
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.isNohing()) {
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
- * Userful in order to avoid ambiguous yied types
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 specialiation representing an absence of any value
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 patter matching peeker function
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 patter matching transformer function
276
+ * Maybe pattern matching extractor function
271
277
  *
272
- * Applied to 'just value' returns 'just op.just(value)'
273
- * Applied to 'nothing' returns 'just op.nothing()'
278
+ * Applied to 'just value' returns op.just(value)
279
+ * Applied to 'nothing' returns op.nothing()
274
280
  *
275
- * @template R2 just transformer function's return type
276
- * @template R3 nothing transformer function's return type
277
- * @param op.just transformer to be invoked with underlying value in case of just
278
- * @param op.nothing transformer to be invoked in case of nothing
279
- * @returns 'just op.just(value)' or 'just op.nothing()'
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 cases
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 witjout invoking composition function
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 patter matching composition function
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.isNohing()) {
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
- * Userful in order to avoid ambiguous yied types
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
- * Genric Maybe monad interface
407
+ * Generic Maybe monad interface
397
408
  *
398
- * As per classic Maybe monad implementation can eithr contain just a value or contain nothing
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
- * Userful for passing as a function to collection transformers
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<never> {
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
- * Userful for passing as a predicate to collection transformers
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
- * Userful for passing as a predicate to collection transformers
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<never> {
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 al east one list element is Just
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 convinient option for typescript is to use ```yield* maybe.generator()``` as othervise one may have to deal with union types
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
- const sequentor = (next: IteratorResult<TT, R>): Maybe<R> => {
559
- return next.done ? (
560
- Maybe.just(next.value)
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
- return Maybe.just(undefined).chain(() => sequentor(generator.next()));
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
  }