t-tasks 1.2.1 → 2.1.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 +1913 -0
- package/dist/t-tasks.esm.js +778 -2
- package/dist/t-tasks.esm.js.map +1 -1
- package/dist/t-tasks.js +814 -2
- package/dist/t-tasks.js.map +1 -1
- package/package.json +12 -7
- package/src/either.ts +135 -45
- package/src/maybe.ts +121 -37
- package/src/task.ts +472 -252
- 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;
|
|
@@ -64,6 +64,7 @@ export interface Right<R, L> {
|
|
|
64
64
|
* Applied to 'right value' returns self without invoking transformer
|
|
65
65
|
* Applied to 'left error' returns 'right op(error)'
|
|
66
66
|
*
|
|
67
|
+
* @template R2 transformer function's return type
|
|
67
68
|
* @param op transformer to be invoked with underlying error
|
|
68
69
|
* @returns 'right value' or 'right op(error)'
|
|
69
70
|
*/
|
|
@@ -72,6 +73,23 @@ export interface Right<R, L> {
|
|
|
72
73
|
// General case
|
|
73
74
|
orMap<R2>(this: Either<R, L>, op: (error: L) => R2): Right<R | R2, never>;
|
|
74
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Either pattern matching extractor function
|
|
78
|
+
*
|
|
79
|
+
* Applied to 'right value' returns op.right(value)
|
|
80
|
+
* Applied to 'left error' returns op.left(error)
|
|
81
|
+
*
|
|
82
|
+
* @template R2 right extractor function's return type
|
|
83
|
+
* @template R3 left extractor function's return type
|
|
84
|
+
* @param op.right extractor to be invoked with underlying value in case of 'right'
|
|
85
|
+
* @param op.left extractor to be invoked with underlying error in case of 'left'
|
|
86
|
+
* @returns op.right(value) or op.left(error)
|
|
87
|
+
*/
|
|
88
|
+
// Right case
|
|
89
|
+
match<R2, R3 = R2>(this: Right<R, L>, op: { right: (value: R) => R2; left: (error: L) => R3 }): R2;
|
|
90
|
+
// General case
|
|
91
|
+
match<R2, R3 = R2>(this: Either<R, L>, op: { right: (value: R) => R2; left: (error: L) => R3 }): R2 | R3;
|
|
92
|
+
|
|
75
93
|
/**
|
|
76
94
|
* Either pattern matching transformer function
|
|
77
95
|
*
|
|
@@ -110,14 +128,14 @@ export interface Right<R, L> {
|
|
|
110
128
|
chain<R2, L2>(this: Either<R, L>, op: (value: R) => Either<R2, L2>): Either<R2, L | L2>;
|
|
111
129
|
|
|
112
130
|
/**
|
|
113
|
-
* Either composition function
|
|
131
|
+
* Either fallback composition function
|
|
114
132
|
*
|
|
115
133
|
* Applied to 'right value' returns self without invoking composition function
|
|
116
134
|
* Applied to 'left error' returns 'op(error)'
|
|
117
135
|
*
|
|
118
136
|
* @template R2 transformer function result's underlying value type
|
|
119
137
|
* @template L2 transformer function result's underlying error type
|
|
120
|
-
* @param op transformer to be invoked with underlying
|
|
138
|
+
* @param op transformer to be invoked with underlying error
|
|
121
139
|
* @returns 'right value' or 'op(error)'
|
|
122
140
|
*/
|
|
123
141
|
// Right cases
|
|
@@ -141,7 +159,7 @@ export interface Right<R, L> {
|
|
|
141
159
|
* @template L3 left transformer function result's underlying error type
|
|
142
160
|
* @param op.right transformer to be invoked with underlying value in case of 'right'
|
|
143
161
|
* @param op.left transformer to be invoked with underlying error in case of 'left'
|
|
144
|
-
* @returns 'op(value)' or 'op(error)'
|
|
162
|
+
* @returns 'op.right(value)' or 'op.left(error)'
|
|
145
163
|
*/
|
|
146
164
|
// Right cases
|
|
147
165
|
matchChain<R2, L2, R3 = R2, L3 = L2>(this: Right<R, L>, op: { right: (value: R) => Right<R2, L2>; left: (error: L) => Right<R3, L3> }): Right<R2, never>;
|
|
@@ -193,13 +211,13 @@ export interface Right<R, L> {
|
|
|
193
211
|
isLeft(): this is Left<R, L>;
|
|
194
212
|
|
|
195
213
|
/**
|
|
196
|
-
* Wrap
|
|
214
|
+
* Wrap Either to singleton generator
|
|
197
215
|
*
|
|
198
|
-
*
|
|
216
|
+
* Useful in order to avoid ambiguous yield types
|
|
199
217
|
*
|
|
200
|
-
* @returns generator of
|
|
218
|
+
* @returns generator of Either wrapping this
|
|
201
219
|
*/
|
|
202
|
-
|
|
220
|
+
generator: EitherGeneratorFunction<[], R, Right<R, L>, R>
|
|
203
221
|
}
|
|
204
222
|
|
|
205
223
|
/**
|
|
@@ -207,7 +225,7 @@ export interface Right<R, L> {
|
|
|
207
225
|
*
|
|
208
226
|
* Either data type specialization representing an erroneous value
|
|
209
227
|
*
|
|
210
|
-
* @
|
|
228
|
+
* @template R underlying value type (needed for type merging, in fact always considered to be never)
|
|
211
229
|
* @template L underlying error type
|
|
212
230
|
*/
|
|
213
231
|
export interface Left<R, L> {
|
|
@@ -230,7 +248,7 @@ export interface Left<R, L> {
|
|
|
230
248
|
* Applied to 'right value' returns self without invoking callback
|
|
231
249
|
* Applied to 'left error' returns self invoking op(error) in process
|
|
232
250
|
*
|
|
233
|
-
* @param op function to be invoked with underlying
|
|
251
|
+
* @param op function to be invoked with underlying error
|
|
234
252
|
* @returns self
|
|
235
253
|
*/
|
|
236
254
|
orTap(op: (error: L) => void): this;
|
|
@@ -268,6 +286,7 @@ export interface Left<R, L> {
|
|
|
268
286
|
* Applied to 'right value' returns self without invoking transformer
|
|
269
287
|
* Applied to 'left error' returns 'right op(error)'
|
|
270
288
|
*
|
|
289
|
+
* @template R2 transformer function's return type
|
|
271
290
|
* @param op transformer to be invoked with underlying error
|
|
272
291
|
* @returns 'right value' or 'right op(error)'
|
|
273
292
|
*/
|
|
@@ -276,6 +295,23 @@ export interface Left<R, L> {
|
|
|
276
295
|
// General case
|
|
277
296
|
orMap<R2>(this: Either<R, L>, op: (error: L) => R2): Right<R | R2, never>;
|
|
278
297
|
|
|
298
|
+
/**
|
|
299
|
+
* Either pattern matching extractor function
|
|
300
|
+
*
|
|
301
|
+
* Applied to 'right value' returns op.right(value)
|
|
302
|
+
* Applied to 'left error' returns op.left(error)
|
|
303
|
+
*
|
|
304
|
+
* @template R2 right extractor function's return type
|
|
305
|
+
* @template R3 left extractor function's return type
|
|
306
|
+
* @param op.right extractor to be invoked with underlying value in case of 'right'
|
|
307
|
+
* @param op.left extractor to be invoked with underlying error in case of 'left'
|
|
308
|
+
* @returns op.right(value) or op.left(error)
|
|
309
|
+
*/
|
|
310
|
+
// Left case
|
|
311
|
+
match<R2, R3 = R2>(this: Left<R, L>, op: { right: (value: R) => R2; left: (error: L) => R3 }): R3;
|
|
312
|
+
// General case
|
|
313
|
+
match<R2, R3 = R2>(this: Either<R, L>, op: { right: (value: R) => R2; left: (error: L) => R3 }): R2 | R3;
|
|
314
|
+
|
|
279
315
|
/**
|
|
280
316
|
* Either pattern matching transformer function
|
|
281
317
|
*
|
|
@@ -304,7 +340,7 @@ export interface Left<R, L> {
|
|
|
304
340
|
* @param op transformer to be invoked with underlying value
|
|
305
341
|
* @returns 'op(value)' or 'left error'
|
|
306
342
|
*/
|
|
307
|
-
//
|
|
343
|
+
// Left cases
|
|
308
344
|
chain<R2, L2>(this: Left<R, L>, op: (value: R) => Right<R2, L2>): Left<never, L>;
|
|
309
345
|
chain<R2, L2>(this: Left<R, L>, op: (value: R) => Left<R2, L2>): Left<never, L>;
|
|
310
346
|
chain<R2, L2>(this: Left<R, L>, op: (value: R) => Either<R2, L2>): Left<never, L>;
|
|
@@ -321,7 +357,7 @@ export interface Left<R, L> {
|
|
|
321
357
|
*
|
|
322
358
|
* @template R2 transformer function result's underlying value type
|
|
323
359
|
* @template L2 transformer function result's underlying error type
|
|
324
|
-
* @param op transformer to be invoked with underlying
|
|
360
|
+
* @param op transformer to be invoked with underlying error
|
|
325
361
|
* @returns 'right value' or 'op(error)'
|
|
326
362
|
*/
|
|
327
363
|
// Left cases
|
|
@@ -345,7 +381,7 @@ export interface Left<R, L> {
|
|
|
345
381
|
* @template L3 left transformer function result's underlying error type
|
|
346
382
|
* @param op.right transformer to be invoked with underlying value in case of 'right'
|
|
347
383
|
* @param op.left transformer to be invoked with underlying error in case of 'left'
|
|
348
|
-
* @returns 'op(value)' or 'op(error)'
|
|
384
|
+
* @returns 'op.right(value)' or 'op.left(error)'
|
|
349
385
|
*/
|
|
350
386
|
// Left cases
|
|
351
387
|
matchChain<R2, L2, R3 = R2, L3 = L2>(this: Left<R, L>, op: { right: (value: R) => Right<R2, L2>; left: (error: L) => Right<R3, L3> }): Right<R3, never>;
|
|
@@ -397,19 +433,19 @@ export interface Left<R, L> {
|
|
|
397
433
|
isLeft(): this is Left<R, L>;
|
|
398
434
|
|
|
399
435
|
/**
|
|
400
|
-
* Wrap
|
|
436
|
+
* Wrap Either to singleton generator
|
|
401
437
|
*
|
|
402
|
-
*
|
|
438
|
+
* Useful in order to avoid ambiguous yield types
|
|
403
439
|
*
|
|
404
|
-
* @returns generator of
|
|
440
|
+
* @returns generator of Either wrapping this
|
|
405
441
|
*/
|
|
406
|
-
|
|
442
|
+
generator: EitherGeneratorFunction<[], R, Left<R, L>, R>
|
|
407
443
|
}
|
|
408
444
|
|
|
409
445
|
/**
|
|
410
446
|
* Either data type: either Right value of type R or Left value of type L
|
|
411
447
|
*
|
|
412
|
-
* As per classic Either monad implementation can
|
|
448
|
+
* As per classic Either monad implementation can either contain a right (correct) value or a left (erroneous) value
|
|
413
449
|
* Used throughout the library to represent the result of failable operations, namely failed tasks
|
|
414
450
|
*
|
|
415
451
|
* @template R underlying value type
|
|
@@ -421,7 +457,7 @@ export namespace Right {
|
|
|
421
457
|
/**
|
|
422
458
|
* Standalone Right value extractor
|
|
423
459
|
*
|
|
424
|
-
*
|
|
460
|
+
* Useful for passing as a function to collection transformers
|
|
425
461
|
*
|
|
426
462
|
* @template R underlying value type
|
|
427
463
|
* @template L underlying error type
|
|
@@ -437,7 +473,7 @@ export namespace Left {
|
|
|
437
473
|
/**
|
|
438
474
|
* Standalone Left error extractor
|
|
439
475
|
*
|
|
440
|
-
*
|
|
476
|
+
* Useful for passing as a function to collection transformers
|
|
441
477
|
*
|
|
442
478
|
* @template R underlying value type
|
|
443
479
|
* @template L underlying error type
|
|
@@ -449,7 +485,23 @@ export namespace Left {
|
|
|
449
485
|
}
|
|
450
486
|
}
|
|
451
487
|
|
|
488
|
+
/**
|
|
489
|
+
* Either generator
|
|
490
|
+
*
|
|
491
|
+
* @template T yielded underlying type
|
|
492
|
+
* @template TT yielded Either type
|
|
493
|
+
* @template R returned underlying type
|
|
494
|
+
*/
|
|
452
495
|
export type EitherGenerator<T, TT extends Either<T, any>, R> = Generator<TT, R, T>;
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* Function returning Either generator (generator function)
|
|
499
|
+
*
|
|
500
|
+
* @template A argument types
|
|
501
|
+
* @template T yielded underlying type
|
|
502
|
+
* @template TT yielded Either type
|
|
503
|
+
* @template R returned underlying type
|
|
504
|
+
*/
|
|
453
505
|
export type EitherGeneratorFunction<A extends unknown[], T, TT extends Either<T, any>, R> = (...args: A) => EitherGenerator<T, TT, R>;
|
|
454
506
|
|
|
455
507
|
export namespace Either {
|
|
@@ -480,6 +532,8 @@ export namespace Either {
|
|
|
480
532
|
*
|
|
481
533
|
* Resolves to 'left error' in case of undefined value and 'right value' otherwise
|
|
482
534
|
*
|
|
535
|
+
* @template R underlying value type
|
|
536
|
+
* @template L underlying error type
|
|
483
537
|
* @param value possibly undefined value
|
|
484
538
|
* @param error error to use in case of undefined value
|
|
485
539
|
* @returns either 'right value' or 'left error'
|
|
@@ -496,8 +550,10 @@ export namespace Either {
|
|
|
496
550
|
*
|
|
497
551
|
* Resolves to 'left error' in case of undefined or null value and 'right value' otherwise
|
|
498
552
|
*
|
|
499
|
-
* @
|
|
500
|
-
* @
|
|
553
|
+
* @template R underlying value type
|
|
554
|
+
* @template L underlying error type
|
|
555
|
+
* @param value possibly undefined or null value
|
|
556
|
+
* @param error error to use in case of undefined or null value
|
|
501
557
|
* @returns either 'right value' or 'left error'
|
|
502
558
|
*/
|
|
503
559
|
export function fromNullable<L>(value: undefined, error: L): Left<never, L>;
|
|
@@ -508,12 +564,33 @@ export namespace Either {
|
|
|
508
564
|
return Either.fromOptional(value, error).chain((v) => (v !== null ? Either.right(value) : Either.left(error)));
|
|
509
565
|
}
|
|
510
566
|
|
|
567
|
+
/**
|
|
568
|
+
* Standalone Either value extractor
|
|
569
|
+
*
|
|
570
|
+
* Applied to 'right value' returns underlying value without using fallback
|
|
571
|
+
* Applied to 'left error' returns fallback
|
|
572
|
+
*
|
|
573
|
+
* @template R underlying value type
|
|
574
|
+
* @template L underlying error type
|
|
575
|
+
* @template R2 fallback value type
|
|
576
|
+
* @param either Either instance
|
|
577
|
+
* @param fallback value to be returned in case of 'left error'
|
|
578
|
+
* @returns underlying value or fallback
|
|
579
|
+
*/
|
|
580
|
+
export function fromEither<R, L>(either: Right<R, L>, fallback: unknown): R;
|
|
581
|
+
export function fromEither<R, L, R2>(either: Left<R, L>, fallback: R2): R2;
|
|
582
|
+
export function fromEither<R, L, R2>(either: Either<R, L>, fallback: R2): R | R2;
|
|
583
|
+
export function fromEither<R, L, R2>(either: Either<R, L>, fallback: R2) {
|
|
584
|
+
return either.match({ right: (value) => value, left: () => fallback });
|
|
585
|
+
}
|
|
586
|
+
|
|
511
587
|
/**
|
|
512
588
|
* Standalone type guard for 'right'
|
|
513
589
|
*
|
|
514
|
-
*
|
|
590
|
+
* Useful for passing as a predicate to collection transformers
|
|
515
591
|
*
|
|
516
592
|
* @template R underlying value type
|
|
593
|
+
* @template L underlying error type
|
|
517
594
|
* @param either Either instance
|
|
518
595
|
* @returns 'true' in case argument is 'right value' (and resolves type to be 'right')
|
|
519
596
|
*/
|
|
@@ -524,9 +601,10 @@ export namespace Either {
|
|
|
524
601
|
/**
|
|
525
602
|
* Standalone type guard for 'left'
|
|
526
603
|
*
|
|
527
|
-
*
|
|
604
|
+
* Useful for passing as a predicate to collection transformers
|
|
528
605
|
*
|
|
529
606
|
* @template R underlying value type
|
|
607
|
+
* @template L underlying error type
|
|
530
608
|
* @param either Either instance
|
|
531
609
|
* @returns 'true' in case argument is 'left error' (and resolves type to be 'left')
|
|
532
610
|
*/
|
|
@@ -537,6 +615,8 @@ export namespace Either {
|
|
|
537
615
|
/**
|
|
538
616
|
* Standalone list predicate
|
|
539
617
|
*
|
|
618
|
+
* @template R underlying value type
|
|
619
|
+
* @template L underlying error type
|
|
540
620
|
* @param eithers a list of Either
|
|
541
621
|
* @returns true in case every list element is Right
|
|
542
622
|
*/
|
|
@@ -547,6 +627,8 @@ export namespace Either {
|
|
|
547
627
|
/**
|
|
548
628
|
* Standalone list predicate
|
|
549
629
|
*
|
|
630
|
+
* @template R underlying value type
|
|
631
|
+
* @template L underlying error type
|
|
550
632
|
* @param eithers a list of Either
|
|
551
633
|
* @returns true in case at least one list element is Right
|
|
552
634
|
*/
|
|
@@ -557,6 +639,8 @@ export namespace Either {
|
|
|
557
639
|
/**
|
|
558
640
|
* Standalone list predicate
|
|
559
641
|
*
|
|
642
|
+
* @template R underlying value type
|
|
643
|
+
* @template L underlying error type
|
|
560
644
|
* @param eithers a list of Either
|
|
561
645
|
* @returns true in case every list element is Left
|
|
562
646
|
*/
|
|
@@ -567,6 +651,8 @@ export namespace Either {
|
|
|
567
651
|
/**
|
|
568
652
|
* Standalone list predicate
|
|
569
653
|
*
|
|
654
|
+
* @template R underlying value type
|
|
655
|
+
* @template L underlying error type
|
|
570
656
|
* @param eithers a list of Either
|
|
571
657
|
* @returns true in case at least one list element is Left
|
|
572
658
|
*/
|
|
@@ -577,30 +663,28 @@ export namespace Either {
|
|
|
577
663
|
/**
|
|
578
664
|
* Create compound Either from generator function
|
|
579
665
|
*
|
|
580
|
-
* Applying yield to
|
|
581
|
-
* However the
|
|
666
|
+
* Applying yield to an Either within the generator function unwraps the Either and returns underlying value in case of success
|
|
667
|
+
* However the convenient option for typescript is to use ```yield* either.generator()``` as otherwise one may have to deal with union types
|
|
582
668
|
*
|
|
583
|
-
* @template
|
|
669
|
+
* @template T yielded underlying type
|
|
670
|
+
* @template TT yielded Either type
|
|
584
671
|
* @template R returned underlying type
|
|
585
|
-
* @param
|
|
586
|
-
* @returns
|
|
587
|
-
* ```
|
|
672
|
+
* @param eitherGeneratorFunction Either generator function
|
|
673
|
+
* @returns Right wrapping the result of generator function or Left
|
|
588
674
|
*/
|
|
589
675
|
export function generate<T, TT extends Either<T, any>, R>(eitherGeneratorFunction: EitherGeneratorFunction<[], T, TT, R>): Either<R, any> {
|
|
590
676
|
const generator = eitherGeneratorFunction();
|
|
677
|
+
let next = generator.next();
|
|
591
678
|
|
|
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
|
-
};
|
|
679
|
+
while (!next.done) {
|
|
680
|
+
if (next.value.isLeft()) {
|
|
681
|
+
return Either.left(next.value.left);
|
|
682
|
+
}
|
|
602
683
|
|
|
603
|
-
|
|
684
|
+
next = generator.next(next.value.right);
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
return Either.right(next.value);
|
|
604
688
|
}
|
|
605
689
|
}
|
|
606
690
|
|
|
@@ -625,7 +709,7 @@ class RightClass<R> implements Right<R, never> {
|
|
|
625
709
|
orMap() {
|
|
626
710
|
return this;
|
|
627
711
|
}
|
|
628
|
-
chain<
|
|
712
|
+
chain<RR extends Either<unknown, unknown>>(op: (value: R) => RR) {
|
|
629
713
|
return op(this.right);
|
|
630
714
|
}
|
|
631
715
|
orChain() {
|
|
@@ -637,13 +721,16 @@ class RightClass<R> implements Right<R, never> {
|
|
|
637
721
|
isLeft(): this is Left<R, never> {
|
|
638
722
|
return false;
|
|
639
723
|
}
|
|
724
|
+
match<R2>(op: { right: (value: R) => R2 }) {
|
|
725
|
+
return op.right(this.right);
|
|
726
|
+
}
|
|
640
727
|
matchTap(op: { right: (value: R) => void }) {
|
|
641
728
|
return this.tap(op.right);
|
|
642
729
|
}
|
|
643
730
|
matchMap<R2>(op: { right: (value: R) => R2 }) {
|
|
644
731
|
return this.map(op.right);
|
|
645
732
|
}
|
|
646
|
-
matchChain<
|
|
733
|
+
matchChain<RR extends Either<unknown, unknown>>(op: { right: (value: R) => RR }) {
|
|
647
734
|
return this.chain(op.right);
|
|
648
735
|
}
|
|
649
736
|
generator() {
|
|
@@ -673,7 +760,7 @@ class LeftClass<L> implements Left<never, L> {
|
|
|
673
760
|
chain() {
|
|
674
761
|
return this;
|
|
675
762
|
}
|
|
676
|
-
orChain<
|
|
763
|
+
orChain<RR extends Either<unknown, unknown>>(op: (error: L) => RR) {
|
|
677
764
|
return op(this.left);
|
|
678
765
|
}
|
|
679
766
|
isRight(): this is Right<never, L> {
|
|
@@ -682,13 +769,16 @@ class LeftClass<L> implements Left<never, L> {
|
|
|
682
769
|
isLeft(): this is Left<never, L> {
|
|
683
770
|
return true;
|
|
684
771
|
}
|
|
772
|
+
match<R2>(op: { left: (error: L) => R2 }) {
|
|
773
|
+
return op.left(this.left);
|
|
774
|
+
}
|
|
685
775
|
matchTap(op: { left: (error: L) => void }) {
|
|
686
776
|
return this.orTap(op.left);
|
|
687
777
|
}
|
|
688
778
|
matchMap<R2>(op: { left: (error: L) => R2 }) {
|
|
689
779
|
return this.orMap(op.left);
|
|
690
780
|
}
|
|
691
|
-
matchChain<
|
|
781
|
+
matchChain<RR extends Either<unknown, unknown>>(op: { left: (error: L) => RR }) {
|
|
692
782
|
return this.orChain(op.left);
|
|
693
783
|
}
|
|
694
784
|
generator() {
|