@jeengbe/prelude 0.1.3 → 0.1.4
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/either.d.mts +71 -6
- package/dist/either.d.mts.map +1 -1
- package/dist/either.mjs +75 -12
- package/dist/either.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/maybe.d.mts +64 -0
- package/dist/maybe.d.mts.map +1 -1
- package/dist/maybe.mjs +61 -0
- package/dist/maybe.mjs.map +1 -1
- package/package.json +1 -1
- package/src/either.ts +88 -18
- package/src/maybe.ts +64 -0
package/dist/either.d.mts
CHANGED
|
@@ -5,37 +5,59 @@ declare abstract class EitherBase<L, R> {
|
|
|
5
5
|
* Maps the value of this Either if it is a Right, performs no operation if this is a Left.
|
|
6
6
|
*/
|
|
7
7
|
map<R2>(fn: (t: R) => R2): Either<L, R2>;
|
|
8
|
+
/**
|
|
9
|
+
* Maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
10
|
+
*/
|
|
8
11
|
mapAsync<R2>(fn: (t: R) => Promise<R2>): EitherP<L, R2>;
|
|
9
12
|
/**
|
|
10
13
|
* Flat maps the value of this Either if it is a Left, performs no operation if this is a Right.
|
|
11
14
|
*/
|
|
12
15
|
leftFlatMap<L2, R2>(fn: (t: L) => Either<L2, R2>): Either<L2, R | R2>;
|
|
16
|
+
/**
|
|
17
|
+
* Flat maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
|
|
18
|
+
*/
|
|
13
19
|
leftFlatMapAsync<L2, R2>(fn: (t: L) => PromiseLike<Either<L2, R2>>): EitherP<L2, R | R2>;
|
|
14
20
|
/**
|
|
15
21
|
* Maps the value of this Either if it is a Left, performs no operation if this is a Right.
|
|
16
22
|
*/
|
|
17
23
|
leftMap<L2>(fn: (t: L) => L2): Either<L2, R>;
|
|
24
|
+
/**
|
|
25
|
+
* Maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
|
|
26
|
+
*/
|
|
18
27
|
leftMapAsync<L2>(fn: (t: L) => Promise<L2>): EitherP<L2, R>;
|
|
19
28
|
/**
|
|
20
29
|
* Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either.
|
|
21
30
|
*/
|
|
22
31
|
bimap<L2, R2>(leftFn: (l: L) => L2, rightFn: (r: R) => R2): Either<L2, R2>;
|
|
32
|
+
/**
|
|
33
|
+
* Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either, asynchronously.
|
|
34
|
+
*/
|
|
23
35
|
bimapAsync<L2, R2>(leftFn: (l: L) => Promise<L2>, rightFn: (r: R) => Promise<R2>): EitherP<L2, R2>;
|
|
24
36
|
/**
|
|
25
37
|
* Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.
|
|
26
38
|
*/
|
|
27
39
|
tap(fn: (t: R) => void): Either<L, R>;
|
|
40
|
+
/**
|
|
41
|
+
* Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
42
|
+
*/
|
|
28
43
|
tapAsync(fn: (t: R) => Promise<void>): EitherP<L, R>;
|
|
29
44
|
/**
|
|
30
45
|
* Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.
|
|
31
46
|
* If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.
|
|
32
47
|
*/
|
|
33
48
|
flatTap<L2>(fn: (t: R) => Either<L2, void>): Either<L | L2, R>;
|
|
49
|
+
/**
|
|
50
|
+
* Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
51
|
+
* If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.
|
|
52
|
+
*/
|
|
34
53
|
flatTapAsync<L2>(fn: (t: R) => PromiseLike<Either<L2, void>>): EitherP<L | L2, R>;
|
|
35
54
|
/**
|
|
36
55
|
* Flat maps the value of this Either if it is a Right, performs no operation if this is a Left.
|
|
37
56
|
*/
|
|
38
57
|
flatMap<L2, R2>(fn: (t: R) => Either<L2, R2>): Either<L | L2, R2>;
|
|
58
|
+
/**
|
|
59
|
+
* Flat maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
60
|
+
*/
|
|
39
61
|
flatMapAsync<L2, R2>(fn: (t: R) => PromiseLike<Either<L2, R2>>): EitherP<L | L2, R2>;
|
|
40
62
|
/**
|
|
41
63
|
* Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns the result.
|
|
@@ -80,16 +102,18 @@ declare class Left<L> extends EitherBase<L, never> {
|
|
|
80
102
|
constructor(value: L);
|
|
81
103
|
fold<U1, U2>(leftFn: (l: L) => U1, _rightFn: (r: never) => U2): U1 | U2;
|
|
82
104
|
getLeft(): L;
|
|
105
|
+
toString(): string;
|
|
106
|
+
get [Symbol.toStringTag](): string;
|
|
83
107
|
}
|
|
84
108
|
declare class Right<R> extends EitherBase<never, R> {
|
|
85
109
|
private readonly value;
|
|
86
110
|
constructor(value: R);
|
|
87
111
|
fold<U1, U2>(_leftFn: (l: never) => U1, rightFn: (r: R) => U2): U1 | U2;
|
|
88
112
|
get(): R;
|
|
113
|
+
toString(): string;
|
|
114
|
+
get [Symbol.toStringTag](): string;
|
|
89
115
|
}
|
|
90
116
|
/**
|
|
91
|
-
* Mimics the [Cats Either[L, R]](https://typelevel.org/cats/datatypes/either.html) type.
|
|
92
|
-
*
|
|
93
117
|
* Either<L, R> is a union of Left<L> and Right<R>, so narrowing works in both directions:
|
|
94
118
|
*
|
|
95
119
|
* ```ts
|
|
@@ -112,11 +136,22 @@ declare namespace Either {
|
|
|
112
136
|
* Creates a new Right Either with the provided value.
|
|
113
137
|
*/
|
|
114
138
|
function right<R>(value: R): Either<never, R>;
|
|
139
|
+
/**
|
|
140
|
+
* Creates a Right Either from a Maybe if it is defined, or a Left Either from the result of the provided function otherwise.
|
|
141
|
+
*/
|
|
115
142
|
function fromMaybe<L, R>(value: Maybe<R>, leftValue: () => L): Either<L, R>;
|
|
143
|
+
/**
|
|
144
|
+
* Creates a Right Either from the result of `rightFn` if `bool` is true, or a Left Either from the result of `leftFn` otherwise.
|
|
145
|
+
*/
|
|
116
146
|
function cond<L, R>(bool: boolean, leftFn: () => L, rightFn: () => R): Either<L, R>;
|
|
117
147
|
}
|
|
118
148
|
/**
|
|
119
|
-
*
|
|
149
|
+
* Asynchronous version of @{link Either}, allowing for asynchronous operations on the values of the Either.
|
|
150
|
+
*
|
|
151
|
+
* ```ts
|
|
152
|
+
* declare const e: EitherP<string, number>;
|
|
153
|
+
*
|
|
154
|
+
* const result = await e.get(); // result is of type Maybe<number>
|
|
120
155
|
*/
|
|
121
156
|
declare class EitherP<L, R> implements PromiseLike<Either<L, R>> {
|
|
122
157
|
private readonly value;
|
|
@@ -125,37 +160,59 @@ declare class EitherP<L, R> implements PromiseLike<Either<L, R>> {
|
|
|
125
160
|
* Maps the value of this Either if it is a Right, performs no operation if this is a Left.
|
|
126
161
|
*/
|
|
127
162
|
map<R2>(fn: (t: R) => R2): EitherP<L, R2>;
|
|
163
|
+
/**
|
|
164
|
+
* Maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
165
|
+
*/
|
|
128
166
|
mapAsync<R2>(fn: (t: R) => Promise<R2>): EitherP<L, R2>;
|
|
129
167
|
/**
|
|
130
168
|
* Maps the value of this Either if it is a Left, performs no operation if this is a Right.
|
|
131
169
|
*/
|
|
132
170
|
leftMap<L2>(fn: (t: L) => L2): EitherP<L2, R>;
|
|
171
|
+
/**
|
|
172
|
+
* Maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
|
|
173
|
+
*/
|
|
133
174
|
leftMapAsync<L2>(fn: (t: L) => Promise<L2>): EitherP<L2, R>;
|
|
134
175
|
/**
|
|
135
176
|
* Flat maps the value of this Either if it is a Left, performs no operation if this is a Right.
|
|
136
177
|
*/
|
|
137
178
|
leftFlatMap<L2, R2>(fn: (t: L) => Either<L2, R2>): EitherP<L2, R | R2>;
|
|
179
|
+
/**
|
|
180
|
+
* Flat maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
|
|
181
|
+
*/
|
|
138
182
|
leftFlatMapAsync<L2, R2>(fn: (t: L) => PromiseLike<Either<L2, R2>>): EitherP<L2, R | R2>;
|
|
139
183
|
/**
|
|
140
184
|
* Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either.
|
|
141
185
|
*/
|
|
142
186
|
bimap<L2, R2>(leftFn: (l: L) => L2, rightFn: (r: R) => R2): EitherP<L2, R2>;
|
|
187
|
+
/**
|
|
188
|
+
* Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either, asynchronously.
|
|
189
|
+
*/
|
|
143
190
|
bimapAsync<L2, R2>(leftFn: (l: L) => Promise<L2>, rightFn: (r: R) => Promise<R2>): EitherP<L2, R2>;
|
|
144
191
|
/**
|
|
145
192
|
* Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.
|
|
146
193
|
*/
|
|
147
194
|
tap(fn: (t: R) => void): EitherP<L, R>;
|
|
195
|
+
/**
|
|
196
|
+
* Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
197
|
+
*/
|
|
148
198
|
tapAsync(fn: (t: R) => Promise<void>): EitherP<L, R>;
|
|
149
199
|
/**
|
|
150
200
|
* Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.
|
|
151
201
|
* If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.
|
|
152
202
|
*/
|
|
153
203
|
flatTap<L2>(fn: (t: R) => Either<L2, void>): EitherP<L | L2, R>;
|
|
204
|
+
/**
|
|
205
|
+
* Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
206
|
+
* If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.
|
|
207
|
+
*/
|
|
154
208
|
flatTapAsync<L2>(fn: (t: R) => PromiseLike<Either<L2, void>>): EitherP<L | L2, R>;
|
|
155
209
|
/**
|
|
156
210
|
* Flat maps the value of this Either if it is a Right, performs no operation if this is a Left.
|
|
157
211
|
*/
|
|
158
212
|
flatMap<L2, R2>(fn: (t: R) => Either<L2, R2>): EitherP<L | L2, R2>;
|
|
213
|
+
/**
|
|
214
|
+
* Flat maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
215
|
+
*/
|
|
159
216
|
flatMapAsync<L2, R2>(fn: (t: R) => PromiseLike<Either<L2, R2>>): EitherP<L | L2, R2>;
|
|
160
217
|
/**
|
|
161
218
|
* Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns the result.
|
|
@@ -202,15 +259,23 @@ declare class EitherP<L, R> implements PromiseLike<Either<L, R>> {
|
|
|
202
259
|
* Creates a new Right EitherP with the provided value.
|
|
203
260
|
*/
|
|
204
261
|
static right<R>(value: Promise<R>): EitherP<never, R>;
|
|
262
|
+
/**
|
|
263
|
+
* Creates a Right EitherP from a Promise of a Maybe if it resolves to a defined value, or a Left EitherP from the result of the provided function otherwise.
|
|
264
|
+
*/
|
|
205
265
|
static fromMaybe<L, R>(value: Promise<Maybe<R>>, leftValue: () => Promise<L>): EitherP<L, R>;
|
|
206
266
|
/**
|
|
207
|
-
*
|
|
267
|
+
* Creates a new EitherP from a Promise of an Either.
|
|
208
268
|
*/
|
|
209
|
-
static fromEither<L, R>(either: PromiseLike<Either<L, R>>): EitherP<L, R>;
|
|
210
269
|
static fromPromise<L, R>(either: PromiseLike<Either<L, R>>): EitherP<L, R>;
|
|
270
|
+
/**
|
|
271
|
+
* Creates a new Right EitherP if the provided Promise resolves to true, or a new Left EitherP otherwise.
|
|
272
|
+
*/
|
|
211
273
|
static cond<L, R>(bool: Promise<boolean>, leftFn: () => Promise<L>, rightFn: () => Promise<R>): EitherP<L, R>;
|
|
274
|
+
/**
|
|
275
|
+
* Resolves this EitherP to its underlying Either, allowing `await` usage on EitherP instances.
|
|
276
|
+
*/
|
|
212
277
|
then<U>(onfulfilled?: (value: Either<L, R>) => U | PromiseLike<U>): PromiseLike<U>;
|
|
213
278
|
}
|
|
214
279
|
//#endregion
|
|
215
|
-
export { Either, EitherP, Left, Right };
|
|
280
|
+
export { Either, EitherBase, EitherP, Left, Right };
|
|
216
281
|
//# sourceMappingURL=either.d.mts.map
|
package/dist/either.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"either.d.mts","names":[],"sources":["../src/either.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"either.d.mts","names":[],"sources":["../src/either.ts"],"mappings":"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"}
|
package/dist/either.mjs
CHANGED
|
@@ -8,6 +8,9 @@ var EitherBase = class {
|
|
|
8
8
|
map(fn) {
|
|
9
9
|
return this.flatMap((value) => Either.right(fn(value)));
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
13
|
+
*/
|
|
11
14
|
mapAsync(fn) {
|
|
12
15
|
return EitherP.fromPromise(toEitherPromise(this)).mapAsync(fn);
|
|
13
16
|
}
|
|
@@ -17,6 +20,9 @@ var EitherBase = class {
|
|
|
17
20
|
leftFlatMap(fn) {
|
|
18
21
|
return this.fold((l) => fn(l), (r) => Either.right(r));
|
|
19
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Flat maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
|
|
25
|
+
*/
|
|
20
26
|
leftFlatMapAsync(fn) {
|
|
21
27
|
return EitherP.fromPromise(toEitherPromise(this)).leftFlatMapAsync(fn);
|
|
22
28
|
}
|
|
@@ -26,6 +32,9 @@ var EitherBase = class {
|
|
|
26
32
|
leftMap(fn) {
|
|
27
33
|
return this.fold((l) => Either.left(fn(l)), (r) => Either.right(r));
|
|
28
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
|
|
37
|
+
*/
|
|
29
38
|
leftMapAsync(fn) {
|
|
30
39
|
return EitherP.fromPromise(toEitherPromise(this)).leftMapAsync(fn);
|
|
31
40
|
}
|
|
@@ -35,6 +44,9 @@ var EitherBase = class {
|
|
|
35
44
|
bimap(leftFn, rightFn) {
|
|
36
45
|
return this.fold((l) => Either.left(leftFn(l)), (r) => Either.right(rightFn(r)));
|
|
37
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either, asynchronously.
|
|
49
|
+
*/
|
|
38
50
|
bimapAsync(leftFn, rightFn) {
|
|
39
51
|
return EitherP.fromPromise(toEitherPromise(this)).bimapAsync(leftFn, rightFn);
|
|
40
52
|
}
|
|
@@ -47,6 +59,9 @@ var EitherBase = class {
|
|
|
47
59
|
return Either.right(value);
|
|
48
60
|
});
|
|
49
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
64
|
+
*/
|
|
50
65
|
tapAsync(fn) {
|
|
51
66
|
return EitherP.fromPromise(toEitherPromise(this)).tapAsync(fn);
|
|
52
67
|
}
|
|
@@ -57,6 +72,10 @@ var EitherBase = class {
|
|
|
57
72
|
flatTap(fn) {
|
|
58
73
|
return this.flatMap((value) => fn(value).map(() => value));
|
|
59
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
77
|
+
* If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.
|
|
78
|
+
*/
|
|
60
79
|
flatTapAsync(fn) {
|
|
61
80
|
return EitherP.fromPromise(toEitherPromise(this)).flatTapAsync(fn);
|
|
62
81
|
}
|
|
@@ -66,6 +85,9 @@ var EitherBase = class {
|
|
|
66
85
|
flatMap(fn) {
|
|
67
86
|
return this.fold((l) => Either.left(l), (r) => fn(r));
|
|
68
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Flat maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
90
|
+
*/
|
|
69
91
|
flatMapAsync(fn) {
|
|
70
92
|
return EitherP.fromPromise(toEitherPromise(this)).flatMapAsync(fn);
|
|
71
93
|
}
|
|
@@ -99,15 +121,11 @@ var EitherBase = class {
|
|
|
99
121
|
/**
|
|
100
122
|
* Gets the right value if this is a Right or undefined if it's a Left.
|
|
101
123
|
*/
|
|
102
|
-
get() {
|
|
103
|
-
return this.fold(() => void 0, (r) => r);
|
|
104
|
-
}
|
|
124
|
+
get() {}
|
|
105
125
|
/**
|
|
106
126
|
* Returns the left value if this is a Left or undefined if it's a Right.
|
|
107
127
|
*/
|
|
108
|
-
getLeft() {
|
|
109
|
-
return this.fold((l) => l, () => void 0);
|
|
110
|
-
}
|
|
128
|
+
getLeft() {}
|
|
111
129
|
/**
|
|
112
130
|
* Gets the right value if this is a Right or the result of the provided function if it's a Left.
|
|
113
131
|
*/
|
|
@@ -130,6 +148,12 @@ var Left = class extends EitherBase {
|
|
|
130
148
|
getLeft() {
|
|
131
149
|
return this.value;
|
|
132
150
|
}
|
|
151
|
+
toString() {
|
|
152
|
+
return `Left(${String(this.value)})`;
|
|
153
|
+
}
|
|
154
|
+
get [Symbol.toStringTag]() {
|
|
155
|
+
return "Left";
|
|
156
|
+
}
|
|
133
157
|
};
|
|
134
158
|
var Right = class extends EitherBase {
|
|
135
159
|
value;
|
|
@@ -143,6 +167,12 @@ var Right = class extends EitherBase {
|
|
|
143
167
|
get() {
|
|
144
168
|
return this.value;
|
|
145
169
|
}
|
|
170
|
+
toString() {
|
|
171
|
+
return `Right(${String(this.value)})`;
|
|
172
|
+
}
|
|
173
|
+
get [Symbol.toStringTag]() {
|
|
174
|
+
return "Right";
|
|
175
|
+
}
|
|
146
176
|
};
|
|
147
177
|
let Either;
|
|
148
178
|
(function(_Either) {
|
|
@@ -164,7 +194,12 @@ let Either;
|
|
|
164
194
|
_Either.cond = cond;
|
|
165
195
|
})(Either || (Either = {}));
|
|
166
196
|
/**
|
|
167
|
-
*
|
|
197
|
+
* Asynchronous version of @{link Either}, allowing for asynchronous operations on the values of the Either.
|
|
198
|
+
*
|
|
199
|
+
* ```ts
|
|
200
|
+
* declare const e: EitherP<string, number>;
|
|
201
|
+
*
|
|
202
|
+
* const result = await e.get(); // result is of type Maybe<number>
|
|
168
203
|
*/
|
|
169
204
|
var EitherP = class EitherP {
|
|
170
205
|
value;
|
|
@@ -177,6 +212,9 @@ var EitherP = class EitherP {
|
|
|
177
212
|
map(fn) {
|
|
178
213
|
return new EitherP(this.value.then((e) => e.map(fn)));
|
|
179
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* Maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
217
|
+
*/
|
|
180
218
|
mapAsync(fn) {
|
|
181
219
|
return this.flatMapAsync(async (value) => Either.right(await fn(value)));
|
|
182
220
|
}
|
|
@@ -186,6 +224,9 @@ var EitherP = class EitherP {
|
|
|
186
224
|
leftMap(fn) {
|
|
187
225
|
return new EitherP(this.value.then((e) => e.leftMap(fn)));
|
|
188
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* Maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
|
|
229
|
+
*/
|
|
189
230
|
leftMapAsync(fn) {
|
|
190
231
|
return new EitherP(this.value.then(async (e) => await e.fold(async (l) => Either.left(await fn(l)), async (r) => Either.right(r))));
|
|
191
232
|
}
|
|
@@ -195,6 +236,9 @@ var EitherP = class EitherP {
|
|
|
195
236
|
leftFlatMap(fn) {
|
|
196
237
|
return new EitherP(this.value.then((e) => e.leftFlatMap(fn)));
|
|
197
238
|
}
|
|
239
|
+
/**
|
|
240
|
+
* Flat maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
|
|
241
|
+
*/
|
|
198
242
|
leftFlatMapAsync(fn) {
|
|
199
243
|
return new EitherP(this.value.then(async (e) => await e.fold(async (left) => await fn(left), async (right) => Either.right(right))));
|
|
200
244
|
}
|
|
@@ -204,6 +248,9 @@ var EitherP = class EitherP {
|
|
|
204
248
|
bimap(leftFn, rightFn) {
|
|
205
249
|
return new EitherP(this.value.then((e) => e.bimap(leftFn, rightFn)));
|
|
206
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either, asynchronously.
|
|
253
|
+
*/
|
|
207
254
|
bimapAsync(leftFn, rightFn) {
|
|
208
255
|
return new EitherP(this.value.then(async (e) => await e.fold(async (l) => Either.left(await leftFn(l)), async (r) => Either.right(await rightFn(r)))));
|
|
209
256
|
}
|
|
@@ -213,6 +260,9 @@ var EitherP = class EitherP {
|
|
|
213
260
|
tap(fn) {
|
|
214
261
|
return new EitherP(this.value.then((e) => e.tap(fn)));
|
|
215
262
|
}
|
|
263
|
+
/**
|
|
264
|
+
* Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
265
|
+
*/
|
|
216
266
|
tapAsync(fn) {
|
|
217
267
|
return this.flatMapAsync(async (value) => {
|
|
218
268
|
await fn(value);
|
|
@@ -226,6 +276,10 @@ var EitherP = class EitherP {
|
|
|
226
276
|
flatTap(fn) {
|
|
227
277
|
return new EitherP(this.value.then((e) => e.flatTap(fn)));
|
|
228
278
|
}
|
|
279
|
+
/**
|
|
280
|
+
* Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
281
|
+
* If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.
|
|
282
|
+
*/
|
|
229
283
|
flatTapAsync(fn) {
|
|
230
284
|
return this.flatMapAsync(async (value) => (await fn(value)).map(() => value));
|
|
231
285
|
}
|
|
@@ -235,6 +289,9 @@ var EitherP = class EitherP {
|
|
|
235
289
|
flatMap(fn) {
|
|
236
290
|
return new EitherP(this.value.then((e) => e.flatMap(fn)));
|
|
237
291
|
}
|
|
292
|
+
/**
|
|
293
|
+
* Flat maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
294
|
+
*/
|
|
238
295
|
flatMapAsync(fn) {
|
|
239
296
|
return new EitherP(this.value.then((e) => e.fold(async (left) => Either.left(left), (right) => fn(right))));
|
|
240
297
|
}
|
|
@@ -301,26 +358,32 @@ var EitherP = class EitherP {
|
|
|
301
358
|
static right(value) {
|
|
302
359
|
return new EitherP(value.then((v) => Either.right(v)));
|
|
303
360
|
}
|
|
361
|
+
/**
|
|
362
|
+
* Creates a Right EitherP from a Promise of a Maybe if it resolves to a defined value, or a Left EitherP from the result of the provided function otherwise.
|
|
363
|
+
*/
|
|
304
364
|
static fromMaybe(value, leftValue) {
|
|
305
365
|
return new EitherP(value.then(async (v) => isDefined(v) ? Either.right(v) : Either.left(await leftValue())));
|
|
306
366
|
}
|
|
307
367
|
/**
|
|
308
|
-
*
|
|
368
|
+
* Creates a new EitherP from a Promise of an Either.
|
|
309
369
|
*/
|
|
310
|
-
static fromEither(either) {
|
|
311
|
-
return new EitherP(either);
|
|
312
|
-
}
|
|
313
370
|
static fromPromise(either) {
|
|
314
371
|
return new EitherP(either);
|
|
315
372
|
}
|
|
373
|
+
/**
|
|
374
|
+
* Creates a new Right EitherP if the provided Promise resolves to true, or a new Left EitherP otherwise.
|
|
375
|
+
*/
|
|
316
376
|
static cond(bool, leftFn, rightFn) {
|
|
317
377
|
return new EitherP(bool.then(async (b) => b ? Either.right(await rightFn()) : Either.left(await leftFn())));
|
|
318
378
|
}
|
|
379
|
+
/**
|
|
380
|
+
* Resolves this EitherP to its underlying Either, allowing `await` usage on EitherP instances.
|
|
381
|
+
*/
|
|
319
382
|
then(onfulfilled) {
|
|
320
383
|
return this.value.then(onfulfilled);
|
|
321
384
|
}
|
|
322
385
|
};
|
|
323
386
|
|
|
324
387
|
//#endregion
|
|
325
|
-
export { Either, EitherP, Left, Right };
|
|
388
|
+
export { Either, EitherBase, EitherP, Left, Right };
|
|
326
389
|
//# sourceMappingURL=either.mjs.map
|
package/dist/either.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"either.mjs","names":[],"sources":["../src/either.ts"],"sourcesContent":["import type { Maybe } from './maybe.js';\nimport { isDefined } from './maybe.js';\n\n// Note that xxxAsync implementations in Either all look like:\n// EitherP.fromPromise(toEitherPromise(this)).xxxAsync(...)\n//\n// And conversely, xxx implementations in EitherP all look like:\n// new EitherP(this.value.then(e => e.xxx(...)))\n\nabstract class EitherBase<L, R> {\n /**\n * Maps the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n map<R2>(fn: (t: R) => R2): Either<L, R2> {\n return this.flatMap((value) => Either.right(fn(value)));\n }\n\n mapAsync<R2>(fn: (t: R) => Promise<R2>): EitherP<L, R2> {\n return EitherP.fromPromise(toEitherPromise(this)).mapAsync(fn);\n }\n\n /**\n * Flat maps the value of this Either if it is a Left, performs no operation if this is a Right.\n */\n leftFlatMap<L2, R2>(fn: (t: L) => Either<L2, R2>): Either<L2, R | R2> {\n return this.fold(\n (l) => fn(l),\n (r) => Either.right(r),\n );\n }\n\n leftFlatMapAsync<L2, R2>(fn: (t: L) => PromiseLike<Either<L2, R2>>): EitherP<L2, R | R2> {\n return EitherP.fromPromise(toEitherPromise(this)).leftFlatMapAsync(fn);\n }\n\n /**\n * Maps the value of this Either if it is a Left, performs no operation if this is a Right.\n */\n leftMap<L2>(fn: (t: L) => L2): Either<L2, R> {\n return this.fold(\n (l) => Either.left(fn(l)),\n (r) => Either.right(r),\n );\n }\n\n leftMapAsync<L2>(fn: (t: L) => Promise<L2>): EitherP<L2, R> {\n return EitherP.fromPromise(toEitherPromise(this)).leftMapAsync(fn);\n }\n\n /**\n * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either.\n */\n bimap<L2, R2>(leftFn: (l: L) => L2, rightFn: (r: R) => R2): Either<L2, R2> {\n return this.fold(\n (l) => Either.left(leftFn(l)),\n (r) => Either.right(rightFn(r)),\n );\n }\n\n bimapAsync<L2, R2>(\n leftFn: (l: L) => Promise<L2>,\n rightFn: (r: R) => Promise<R2>,\n ): EitherP<L2, R2> {\n return EitherP.fromPromise(toEitherPromise(this)).bimapAsync(leftFn, rightFn);\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n tap(fn: (t: R) => void): Either<L, R> {\n return this.flatMap((value) => {\n fn(value);\n return Either.right(value);\n });\n }\n\n tapAsync(fn: (t: R) => Promise<void>): EitherP<L, R> {\n return EitherP.fromPromise(toEitherPromise(this)).tapAsync(fn);\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.\n * If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.\n */\n flatTap<L2>(fn: (t: R) => Either<L2, void>): Either<L | L2, R> {\n return this.flatMap((value) => fn(value).map(() => value));\n }\n\n flatTapAsync<L2>(fn: (t: R) => PromiseLike<Either<L2, void>>): EitherP<L | L2, R> {\n return EitherP.fromPromise(toEitherPromise(this)).flatTapAsync(fn);\n }\n\n /**\n * Flat maps the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n flatMap<L2, R2>(fn: (t: R) => Either<L2, R2>): Either<L | L2, R2> {\n return this.fold(\n (l) => Either.left(l),\n (r) => fn(r),\n );\n }\n\n flatMapAsync<L2, R2>(fn: (t: R) => PromiseLike<Either<L2, R2>>): EitherP<L | L2, R2> {\n return EitherP.fromPromise(toEitherPromise(this)).flatMapAsync(fn);\n }\n\n /**\n * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns the result.\n */\n abstract fold<U1, U2>(leftFn: (l: L) => U1, rightFn: (r: R) => U2): U1 | U2;\n\n /**\n * Allows to deconstruct the Either using:\n *\n * @example\n *\n * ```ts\n * declare const e: Either<string, number>;\n *\n * const [left, right] = e.pair();\n * ```\n *\n */\n pair(): [Maybe<L>, Maybe<R>] {\n return [this.getLeft(), this.get()];\n }\n\n /**\n * Returns true if this Either is a Right, false otherwise.\n */\n isRight(): this is Right<R> {\n return this.fold(\n () => false,\n () => true,\n );\n }\n\n /**\n * Returns true if this Either is a Left, false otherwise.\n */\n isLeft(): this is Left<L> {\n return this.fold(\n () => true,\n () => false,\n );\n }\n\n /**\n * Gets the right value if this is a Right or undefined if it's a Left.\n */\n get(): Maybe<R> {\n return this.fold(\n () => undefined,\n (r) => r,\n );\n }\n\n /**\n * Returns the left value if this is a Left or undefined if it's a Right.\n */\n getLeft(): Maybe<L> {\n return this.fold(\n (l) => l,\n () => undefined,\n );\n }\n\n /**\n * Gets the right value if this is a Right or the result of the provided function if it's a Left.\n */\n getOrElse<T>(defaultValue: (l: L) => T): R | T {\n return this.fold(\n (l) => defaultValue(l),\n (r) => r,\n );\n }\n}\n\n// EitherBase is abstract with only Left/Right as concrete subclasses; the cast is always valid.\nfunction toEitherPromise<L, R>(e: EitherBase<L, R>): Promise<Either<L, R>> {\n return Promise.resolve(e as unknown as Either<L, R>);\n}\n\nexport class Left<L> extends EitherBase<L, never> {\n constructor(private readonly value: L) {\n super();\n }\n\n fold<U1, U2>(leftFn: (l: L) => U1, _rightFn: (r: never) => U2): U1 | U2 {\n return leftFn(this.value);\n }\n\n override getLeft(): L {\n return this.value;\n }\n}\n\nexport class Right<R> extends EitherBase<never, R> {\n constructor(private readonly value: R) {\n super();\n }\n\n fold<U1, U2>(_leftFn: (l: never) => U1, rightFn: (r: R) => U2): U1 | U2 {\n return rightFn(this.value);\n }\n\n override get(): R {\n return this.value;\n }\n}\n\n/**\n * Mimics the [Cats Either[L, R]](https://typelevel.org/cats/datatypes/either.html) type.\n *\n * Either<L, R> is a union of Left<L> and Right<R>, so narrowing works in both directions:\n *\n * ```ts\n * declare const e: Either<string, number>;\n *\n * if (e.isLeft()) {\n * e; // Left<string>\n * } else {\n * e; // Right<number>\n * }\n * ```\n */\nexport type Either<L, R> = Left<L> | Right<R>;\n\nexport namespace Either {\n /**\n * Creates a new Left Either with the provided value.\n */\n export function left<L>(value: L): Either<L, never> {\n return new Left(value);\n }\n\n /**\n * Creates a new Right Either with the provided value.\n */\n export function right<R>(value: R): Either<never, R> {\n return new Right(value);\n }\n\n export function fromMaybe<L, R>(value: Maybe<R>, leftValue: () => L): Either<L, R> {\n return isDefined(value) ? Either.right(value) : Either.left(leftValue());\n }\n\n export function cond<L, R>(bool: boolean, leftFn: () => L, rightFn: () => R): Either<L, R> {\n return bool ? Either.right(rightFn()) : Either.left(leftFn());\n }\n}\n\n/**\n * Mimics the [Cats EitherT[Future, L, R]](https://typelevel.org/cats/datatypes/eithert.html) type.\n */\nexport class EitherP<L, R> implements PromiseLike<Either<L, R>> {\n private constructor(private readonly value: PromiseLike<Either<L, R>>) {}\n\n /**\n * Maps the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n map<R2>(fn: (t: R) => R2): EitherP<L, R2> {\n return new EitherP(this.value.then((e) => e.map(fn)));\n }\n\n mapAsync<R2>(fn: (t: R) => Promise<R2>): EitherP<L, R2> {\n return this.flatMapAsync(async (value) => Either.right(await fn(value)));\n }\n\n /**\n * Maps the value of this Either if it is a Left, performs no operation if this is a Right.\n */\n leftMap<L2>(fn: (t: L) => L2): EitherP<L2, R> {\n return new EitherP(this.value.then((e) => e.leftMap(fn)));\n }\n\n leftMapAsync<L2>(fn: (t: L) => Promise<L2>): EitherP<L2, R> {\n return new EitherP(\n this.value.then(\n async (e) =>\n await e.fold(\n async (l) => Either.left(await fn(l)),\n async (r) => Either.right(r),\n ),\n ),\n );\n }\n\n /**\n * Flat maps the value of this Either if it is a Left, performs no operation if this is a Right.\n */\n leftFlatMap<L2, R2>(fn: (t: L) => Either<L2, R2>): EitherP<L2, R | R2> {\n return new EitherP(this.value.then((e) => e.leftFlatMap(fn)));\n }\n\n leftFlatMapAsync<L2, R2>(fn: (t: L) => PromiseLike<Either<L2, R2>>): EitherP<L2, R | R2> {\n return new EitherP(\n this.value.then<Either<L2, R | R2>>(\n async (e) =>\n await e.fold(\n async (left) => await fn(left),\n async (right) => Either.right(right),\n ),\n ),\n );\n }\n\n /**\n * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either.\n */\n bimap<L2, R2>(leftFn: (l: L) => L2, rightFn: (r: R) => R2): EitherP<L2, R2> {\n return new EitherP(this.value.then((e) => e.bimap(leftFn, rightFn)));\n }\n\n bimapAsync<L2, R2>(\n leftFn: (l: L) => Promise<L2>,\n rightFn: (r: R) => Promise<R2>,\n ): EitherP<L2, R2> {\n return new EitherP(\n this.value.then(\n async (e) =>\n await e.fold(\n async (l) => Either.left(await leftFn(l)),\n async (r) => Either.right(await rightFn(r)),\n ),\n ),\n );\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n tap(fn: (t: R) => void): EitherP<L, R> {\n return new EitherP(this.value.then((e) => e.tap(fn)));\n }\n\n tapAsync(fn: (t: R) => Promise<void>): EitherP<L, R> {\n return this.flatMapAsync(async (value) => {\n await fn(value);\n return Either.right(value);\n });\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.\n * If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.\n */\n flatTap<L2>(fn: (t: R) => Either<L2, void>): EitherP<L | L2, R> {\n return new EitherP(this.value.then((e) => e.flatTap(fn)));\n }\n\n flatTapAsync<L2>(fn: (t: R) => PromiseLike<Either<L2, void>>): EitherP<L | L2, R> {\n return this.flatMapAsync(async (value) => (await fn(value)).map(() => value));\n }\n\n /**\n * Flat maps the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n flatMap<L2, R2>(fn: (t: R) => Either<L2, R2>): EitherP<L | L2, R2> {\n return new EitherP(this.value.then((e) => e.flatMap(fn)));\n }\n\n flatMapAsync<L2, R2>(fn: (t: R) => PromiseLike<Either<L2, R2>>): EitherP<L | L2, R2> {\n return new EitherP(\n this.value.then<Either<L | L2, R2>>((e) =>\n e.fold(\n async (left) => Either.left(left),\n (right) => fn(right),\n ),\n ),\n );\n }\n\n /**\n * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns the result.\n */\n async fold<U1, U2>(leftFn: (l: L) => U1, rightFn: (r: R) => U2): Promise<U1 | U2> {\n return (await this.value).fold(leftFn, rightFn);\n }\n\n /**\n * Allows to deconstruct the Either using:\n *\n * @example\n *\n * ```ts\n * declare const e: EitherP<string, number>;\n *\n * const [left, right] = await e.pair();\n * ```\n *\n */\n async pair(): Promise<[Maybe<L>, Maybe<R>]> {\n return [await this.getLeft(), await this.get()];\n }\n\n /**\n * Returns true if this Either is a Right, false otherwise.\n */\n async isRight(): Promise<boolean> {\n return (await this.value).isRight();\n }\n\n /**\n * Returns true if this Either is a Left, false otherwise.\n */\n async isLeft(): Promise<boolean> {\n return !(await this.isRight());\n }\n\n /**\n * Gets the right value if this is a Right or undefined if it's a Left.\n */\n async get(): Promise<Maybe<R>> {\n return (await this.value).get();\n }\n\n /**\n * Returns the left value if this is a Left or undefined if it's a Right.\n */\n async getLeft(): Promise<Maybe<L>> {\n return (await this.value).getLeft();\n }\n\n /**\n * Gets the right value if this is a Right or the result of the provided function if it's a Left.\n */\n async getOrElse<T>(defaultValue: (l: L) => T): Promise<R | T> {\n return (await this.value).getOrElse(defaultValue);\n }\n\n /**\n * Creates a new Left EitherP with the provided value.\n */\n static left<L>(value: Promise<L>): EitherP<L, never> {\n return new EitherP(value.then((v) => Either.left(v)));\n }\n\n /**\n * Creates a new Right EitherP with the provided value.\n */\n static right<R>(value: Promise<R>): EitherP<never, R> {\n return new EitherP(value.then((v) => Either.right(v)));\n }\n\n static fromMaybe<L, R>(value: Promise<Maybe<R>>, leftValue: () => Promise<L>): EitherP<L, R> {\n return new EitherP(\n value.then(async (v) => (isDefined(v) ? Either.right(v) : Either.left(await leftValue()))),\n );\n }\n\n /**\n * @deprecated\n */\n static fromEither<L, R>(either: PromiseLike<Either<L, R>>): EitherP<L, R> {\n return new EitherP(either);\n }\n\n static fromPromise<L, R>(either: PromiseLike<Either<L, R>>): EitherP<L, R> {\n return new EitherP(either);\n }\n\n static cond<L, R>(\n bool: Promise<boolean>,\n leftFn: () => Promise<L>,\n rightFn: () => Promise<R>,\n ): EitherP<L, R> {\n return new EitherP(\n bool.then(async (b) => (b ? Either.right(await rightFn()) : Either.left(await leftFn()))),\n );\n }\n\n // oxlint-disable-next-line unicorn/no-thenable -- Deliberately implementing PromiseLike to allow for `await` usage on EitherP instances.\n then<U>(onfulfilled?: (value: Either<L, R>) => U | PromiseLike<U>): PromiseLike<U> {\n return this.value.then(onfulfilled);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"either.mjs","names":[],"sources":["../src/either.ts"],"sourcesContent":["import type { Maybe } from './maybe.js';\nimport { isDefined } from './maybe.js';\n\n// Note that xxxAsync implementations in Either all look like:\n// EitherP.fromPromise(toEitherPromise(this)).xxxAsync(...)\n//\n// And conversely, xxx implementations in EitherP all look like:\n// new EitherP(this.value.then(e => e.xxx(...)))\n\nexport abstract class EitherBase<L, R> {\n /**\n * Maps the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n map<R2>(fn: (t: R) => R2): Either<L, R2> {\n return this.flatMap((value) => Either.right(fn(value)));\n }\n\n /**\n * Maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.\n */\n mapAsync<R2>(fn: (t: R) => Promise<R2>): EitherP<L, R2> {\n return EitherP.fromPromise(toEitherPromise(this)).mapAsync(fn);\n }\n\n /**\n * Flat maps the value of this Either if it is a Left, performs no operation if this is a Right.\n */\n leftFlatMap<L2, R2>(fn: (t: L) => Either<L2, R2>): Either<L2, R | R2> {\n return this.fold(\n (l) => fn(l),\n (r) => Either.right(r),\n );\n }\n\n /**\n * Flat maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.\n */\n leftFlatMapAsync<L2, R2>(fn: (t: L) => PromiseLike<Either<L2, R2>>): EitherP<L2, R | R2> {\n return EitherP.fromPromise(toEitherPromise(this)).leftFlatMapAsync(fn);\n }\n\n /**\n * Maps the value of this Either if it is a Left, performs no operation if this is a Right.\n */\n leftMap<L2>(fn: (t: L) => L2): Either<L2, R> {\n return this.fold(\n (l) => Either.left(fn(l)),\n (r) => Either.right(r),\n );\n }\n\n /**\n * Maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.\n */\n leftMapAsync<L2>(fn: (t: L) => Promise<L2>): EitherP<L2, R> {\n return EitherP.fromPromise(toEitherPromise(this)).leftMapAsync(fn);\n }\n\n /**\n * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either.\n */\n bimap<L2, R2>(leftFn: (l: L) => L2, rightFn: (r: R) => R2): Either<L2, R2> {\n return this.fold(\n (l) => Either.left(leftFn(l)),\n (r) => Either.right(rightFn(r)),\n );\n }\n\n /**\n * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either, asynchronously.\n */\n bimapAsync<L2, R2>(\n leftFn: (l: L) => Promise<L2>,\n rightFn: (r: R) => Promise<R2>,\n ): EitherP<L2, R2> {\n return EitherP.fromPromise(toEitherPromise(this)).bimapAsync(leftFn, rightFn);\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n tap(fn: (t: R) => void): Either<L, R> {\n return this.flatMap((value) => {\n fn(value);\n return Either.right(value);\n });\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.\n */\n tapAsync(fn: (t: R) => Promise<void>): EitherP<L, R> {\n return EitherP.fromPromise(toEitherPromise(this)).tapAsync(fn);\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.\n * If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.\n */\n flatTap<L2>(fn: (t: R) => Either<L2, void>): Either<L | L2, R> {\n return this.flatMap((value) => fn(value).map(() => value));\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.\n * If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.\n */\n flatTapAsync<L2>(fn: (t: R) => PromiseLike<Either<L2, void>>): EitherP<L | L2, R> {\n return EitherP.fromPromise(toEitherPromise(this)).flatTapAsync(fn);\n }\n\n /**\n * Flat maps the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n flatMap<L2, R2>(fn: (t: R) => Either<L2, R2>): Either<L | L2, R2> {\n return this.fold(\n (l) => Either.left(l),\n (r) => fn(r),\n );\n }\n\n /**\n * Flat maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.\n */\n flatMapAsync<L2, R2>(fn: (t: R) => PromiseLike<Either<L2, R2>>): EitherP<L | L2, R2> {\n return EitherP.fromPromise(toEitherPromise(this)).flatMapAsync(fn);\n }\n\n /**\n * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns the result.\n */\n abstract fold<U1, U2>(leftFn: (l: L) => U1, rightFn: (r: R) => U2): U1 | U2;\n\n /**\n * Allows to deconstruct the Either using:\n *\n * @example\n *\n * ```ts\n * declare const e: Either<string, number>;\n *\n * const [left, right] = e.pair();\n * ```\n *\n */\n pair(): [Maybe<L>, Maybe<R>] {\n return [this.getLeft(), this.get()];\n }\n\n /**\n * Returns true if this Either is a Right, false otherwise.\n */\n isRight(): this is Right<R> {\n return this.fold(\n () => false,\n () => true,\n );\n }\n\n /**\n * Returns true if this Either is a Left, false otherwise.\n */\n isLeft(): this is Left<L> {\n return this.fold(\n () => true,\n () => false,\n );\n }\n\n /**\n * Gets the right value if this is a Right or undefined if it's a Left.\n */\n get(): Maybe<R> {\n // Overridden in Right#get\n return undefined;\n }\n\n /**\n * Returns the left value if this is a Left or undefined if it's a Right.\n */\n getLeft(): Maybe<L> {\n // Overridden in Left#getLeft\n return undefined;\n }\n\n /**\n * Gets the right value if this is a Right or the result of the provided function if it's a Left.\n */\n getOrElse<T>(defaultValue: (l: L) => T): R | T {\n return this.fold(\n (l) => defaultValue(l),\n (r) => r,\n );\n }\n}\n\nfunction toEitherPromise<L, R>(e: EitherBase<L, R>): Promise<Either<L, R>> {\n // EitherBase is abstract with only Left/Right as concrete subclasses; the cast is always valid.\n return Promise.resolve(e as unknown as Either<L, R>);\n}\n\nexport class Left<L> extends EitherBase<L, never> {\n constructor(private readonly value: L) {\n super();\n }\n\n fold<U1, U2>(leftFn: (l: L) => U1, _rightFn: (r: never) => U2): U1 | U2 {\n return leftFn(this.value);\n }\n\n override getLeft(): L {\n return this.value;\n }\n\n override toString(): string {\n return `Left(${String(this.value)})`;\n }\n\n get [Symbol.toStringTag](): string {\n return 'Left';\n }\n}\n\nexport class Right<R> extends EitherBase<never, R> {\n constructor(private readonly value: R) {\n super();\n }\n\n fold<U1, U2>(_leftFn: (l: never) => U1, rightFn: (r: R) => U2): U1 | U2 {\n return rightFn(this.value);\n }\n\n override get(): R {\n return this.value;\n }\n\n override toString(): string {\n return `Right(${String(this.value)})`;\n }\n\n get [Symbol.toStringTag](): string {\n return 'Right';\n }\n}\n\n/**\n * Either<L, R> is a union of Left<L> and Right<R>, so narrowing works in both directions:\n *\n * ```ts\n * declare const e: Either<string, number>;\n *\n * if (e.isLeft()) {\n * e; // Left<string>\n * } else {\n * e; // Right<number>\n * }\n * ```\n */\nexport type Either<L, R> = Left<L> | Right<R>;\n\nexport namespace Either {\n /**\n * Creates a new Left Either with the provided value.\n */\n export function left<L>(value: L): Either<L, never> {\n return new Left(value);\n }\n\n /**\n * Creates a new Right Either with the provided value.\n */\n export function right<R>(value: R): Either<never, R> {\n return new Right(value);\n }\n\n /**\n * Creates a Right Either from a Maybe if it is defined, or a Left Either from the result of the provided function otherwise.\n */\n export function fromMaybe<L, R>(value: Maybe<R>, leftValue: () => L): Either<L, R> {\n return isDefined(value) ? Either.right(value) : Either.left(leftValue());\n }\n\n /**\n * Creates a Right Either from the result of `rightFn` if `bool` is true, or a Left Either from the result of `leftFn` otherwise.\n */\n export function cond<L, R>(bool: boolean, leftFn: () => L, rightFn: () => R): Either<L, R> {\n return bool ? Either.right(rightFn()) : Either.left(leftFn());\n }\n}\n\n/**\n * Asynchronous version of @{link Either}, allowing for asynchronous operations on the values of the Either.\n *\n * ```ts\n * declare const e: EitherP<string, number>;\n *\n * const result = await e.get(); // result is of type Maybe<number>\n */\nexport class EitherP<L, R> implements PromiseLike<Either<L, R>> {\n private constructor(private readonly value: PromiseLike<Either<L, R>>) {}\n\n /**\n * Maps the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n map<R2>(fn: (t: R) => R2): EitherP<L, R2> {\n return new EitherP(this.value.then((e) => e.map(fn)));\n }\n\n /**\n * Maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.\n */\n mapAsync<R2>(fn: (t: R) => Promise<R2>): EitherP<L, R2> {\n return this.flatMapAsync(async (value) => Either.right(await fn(value)));\n }\n\n /**\n * Maps the value of this Either if it is a Left, performs no operation if this is a Right.\n */\n leftMap<L2>(fn: (t: L) => L2): EitherP<L2, R> {\n return new EitherP(this.value.then((e) => e.leftMap(fn)));\n }\n\n /**\n * Maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.\n */\n leftMapAsync<L2>(fn: (t: L) => Promise<L2>): EitherP<L2, R> {\n return new EitherP(\n this.value.then(\n async (e) =>\n await e.fold(\n async (l) => Either.left(await fn(l)),\n async (r) => Either.right(r),\n ),\n ),\n );\n }\n\n /**\n * Flat maps the value of this Either if it is a Left, performs no operation if this is a Right.\n */\n leftFlatMap<L2, R2>(fn: (t: L) => Either<L2, R2>): EitherP<L2, R | R2> {\n return new EitherP(this.value.then((e) => e.leftFlatMap(fn)));\n }\n\n /**\n * Flat maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.\n */\n leftFlatMapAsync<L2, R2>(fn: (t: L) => PromiseLike<Either<L2, R2>>): EitherP<L2, R | R2> {\n return new EitherP(\n this.value.then<Either<L2, R | R2>>(\n async (e) =>\n await e.fold(\n async (left) => await fn(left),\n async (right) => Either.right(right),\n ),\n ),\n );\n }\n\n /**\n * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either.\n */\n bimap<L2, R2>(leftFn: (l: L) => L2, rightFn: (r: R) => R2): EitherP<L2, R2> {\n return new EitherP(this.value.then((e) => e.bimap(leftFn, rightFn)));\n }\n\n /**\n * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either, asynchronously.\n */\n bimapAsync<L2, R2>(\n leftFn: (l: L) => Promise<L2>,\n rightFn: (r: R) => Promise<R2>,\n ): EitherP<L2, R2> {\n return new EitherP(\n this.value.then(\n async (e) =>\n await e.fold(\n async (l) => Either.left(await leftFn(l)),\n async (r) => Either.right(await rightFn(r)),\n ),\n ),\n );\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n tap(fn: (t: R) => void): EitherP<L, R> {\n return new EitherP(this.value.then((e) => e.tap(fn)));\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.\n */\n tapAsync(fn: (t: R) => Promise<void>): EitherP<L, R> {\n return this.flatMapAsync(async (value) => {\n await fn(value);\n return Either.right(value);\n });\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left.\n * If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.\n */\n flatTap<L2>(fn: (t: R) => Either<L2, void>): EitherP<L | L2, R> {\n return new EitherP(this.value.then((e) => e.flatTap(fn)));\n }\n\n /**\n * Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.\n * If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.\n */\n flatTapAsync<L2>(fn: (t: R) => PromiseLike<Either<L2, void>>): EitherP<L | L2, R> {\n return this.flatMapAsync(async (value) => (await fn(value)).map(() => value));\n }\n\n /**\n * Flat maps the value of this Either if it is a Right, performs no operation if this is a Left.\n */\n flatMap<L2, R2>(fn: (t: R) => Either<L2, R2>): EitherP<L | L2, R2> {\n return new EitherP(this.value.then((e) => e.flatMap(fn)));\n }\n\n /**\n * Flat maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.\n */\n flatMapAsync<L2, R2>(fn: (t: R) => PromiseLike<Either<L2, R2>>): EitherP<L | L2, R2> {\n return new EitherP(\n this.value.then<Either<L | L2, R2>>((e) =>\n e.fold(\n async (left) => Either.left(left),\n (right) => fn(right),\n ),\n ),\n );\n }\n\n /**\n * Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns the result.\n */\n async fold<U1, U2>(leftFn: (l: L) => U1, rightFn: (r: R) => U2): Promise<U1 | U2> {\n return (await this.value).fold(leftFn, rightFn);\n }\n\n /**\n * Allows to deconstruct the Either using:\n *\n * @example\n *\n * ```ts\n * declare const e: EitherP<string, number>;\n *\n * const [left, right] = await e.pair();\n * ```\n *\n */\n async pair(): Promise<[Maybe<L>, Maybe<R>]> {\n return [await this.getLeft(), await this.get()];\n }\n\n /**\n * Returns true if this Either is a Right, false otherwise.\n */\n async isRight(): Promise<boolean> {\n return (await this.value).isRight();\n }\n\n /**\n * Returns true if this Either is a Left, false otherwise.\n */\n async isLeft(): Promise<boolean> {\n return !(await this.isRight());\n }\n\n /**\n * Gets the right value if this is a Right or undefined if it's a Left.\n */\n async get(): Promise<Maybe<R>> {\n return (await this.value).get();\n }\n\n /**\n * Returns the left value if this is a Left or undefined if it's a Right.\n */\n async getLeft(): Promise<Maybe<L>> {\n return (await this.value).getLeft();\n }\n\n /**\n * Gets the right value if this is a Right or the result of the provided function if it's a Left.\n */\n async getOrElse<T>(defaultValue: (l: L) => T): Promise<R | T> {\n return (await this.value).getOrElse(defaultValue);\n }\n\n /**\n * Creates a new Left EitherP with the provided value.\n */\n static left<L>(value: Promise<L>): EitherP<L, never> {\n return new EitherP(value.then((v) => Either.left(v)));\n }\n\n /**\n * Creates a new Right EitherP with the provided value.\n */\n static right<R>(value: Promise<R>): EitherP<never, R> {\n return new EitherP(value.then((v) => Either.right(v)));\n }\n\n /**\n * Creates a Right EitherP from a Promise of a Maybe if it resolves to a defined value, or a Left EitherP from the result of the provided function otherwise.\n */\n static fromMaybe<L, R>(value: Promise<Maybe<R>>, leftValue: () => Promise<L>): EitherP<L, R> {\n return new EitherP(\n value.then(async (v) => (isDefined(v) ? Either.right(v) : Either.left(await leftValue()))),\n );\n }\n\n /**\n * Creates a new EitherP from a Promise of an Either.\n */\n static fromPromise<L, R>(either: PromiseLike<Either<L, R>>): EitherP<L, R> {\n return new EitherP(either);\n }\n\n /**\n * Creates a new Right EitherP if the provided Promise resolves to true, or a new Left EitherP otherwise.\n */\n static cond<L, R>(\n bool: Promise<boolean>,\n leftFn: () => Promise<L>,\n rightFn: () => Promise<R>,\n ): EitherP<L, R> {\n return new EitherP(\n bool.then(async (b) => (b ? Either.right(await rightFn()) : Either.left(await leftFn()))),\n );\n }\n\n /**\n * Resolves this EitherP to its underlying Either, allowing `await` usage on EitherP instances.\n */\n // oxlint-disable-next-line unicorn/no-thenable -- Deliberately implementing PromiseLike to allow for `await` usage on EitherP instances.\n then<U>(onfulfilled?: (value: Either<L, R>) => U | PromiseLike<U>): PromiseLike<U> {\n return this.value.then(onfulfilled);\n }\n}\n"],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { Maybe, flattenMaybe, ifFalse, ifTrue, isDefined, mapMaybe, matchPair } from "./maybe.mjs";
|
|
2
|
-
import { Either, EitherP, Left, Right } from "./either.mjs";
|
|
3
|
-
export { Either, EitherP, Left, Maybe, Right, flattenMaybe, ifFalse, ifTrue, isDefined, mapMaybe, matchPair };
|
|
2
|
+
import { Either, EitherBase, EitherP, Left, Right } from "./either.mjs";
|
|
3
|
+
export { Either, EitherBase, EitherP, Left, Maybe, Right, flattenMaybe, ifFalse, ifTrue, isDefined, mapMaybe, matchPair };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { flattenMaybe, ifFalse, ifTrue, isDefined, mapMaybe, matchPair } from "./maybe.mjs";
|
|
2
|
-
import { Either, EitherP, Left, Right } from "./either.mjs";
|
|
2
|
+
import { Either, EitherBase, EitherP, Left, Right } from "./either.mjs";
|
|
3
3
|
|
|
4
|
-
export { Either, EitherP, Left, Right, flattenMaybe, ifFalse, ifTrue, isDefined, mapMaybe, matchPair };
|
|
4
|
+
export { Either, EitherBase, EitherP, Left, Right, flattenMaybe, ifFalse, ifTrue, isDefined, mapMaybe, matchPair };
|
package/dist/maybe.d.mts
CHANGED
|
@@ -1,10 +1,74 @@
|
|
|
1
1
|
//#region src/maybe.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Represents a value that may be absent.
|
|
4
|
+
*/
|
|
2
5
|
type Maybe<T> = T | undefined;
|
|
6
|
+
/**
|
|
7
|
+
* Maps the value if it is defined, performs no operation if it is undefined.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
*
|
|
11
|
+
* ```ts
|
|
12
|
+
* const value: Maybe<number> = 5;
|
|
13
|
+
* const result: Maybe<string> = mapMaybe(value, (v) => `Value is ${v}`); // "Value is 5"
|
|
14
|
+
*
|
|
15
|
+
* const undefinedValue: Maybe<number> = undefined;
|
|
16
|
+
* const undefinedResult: Maybe<string> = mapMaybe(undefinedValue, (v) => `Value is ${v}`); // undefined
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
3
19
|
declare function mapMaybe<T, U>(value: Maybe<T>, fn: (value: T) => U): Maybe<U>;
|
|
20
|
+
/**
|
|
21
|
+
* Returns true if the value is defined, false if it is undefined.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
*
|
|
25
|
+
* ```ts
|
|
26
|
+
* const definedValue: Maybe<number> = 5;
|
|
27
|
+
*
|
|
28
|
+
* if (isDefined(definedValue)) {
|
|
29
|
+
* console.log(definedValue + 1); // Output: 6
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
4
33
|
declare function isDefined<T>(value: Maybe<T>): value is T;
|
|
34
|
+
/**
|
|
35
|
+
* Flattens a nested Maybe into a single Maybe.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
*
|
|
39
|
+
* ```ts
|
|
40
|
+
* const nested: Maybe<Maybe<number>> = 5;
|
|
41
|
+
* const flattened: Maybe<number> = flattenMaybe(nested); // 5
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
5
44
|
declare function flattenMaybe<T>(value: Maybe<Maybe<T>>): Maybe<T>;
|
|
45
|
+
/**
|
|
46
|
+
* Returns the result of the provided function if the value is true, undefined otherwise.
|
|
47
|
+
*/
|
|
6
48
|
declare function ifTrue<T>(value: boolean, fn: () => T): Maybe<T>;
|
|
49
|
+
/**
|
|
50
|
+
* Returns the result of the provided function if the value is false, undefined otherwise.
|
|
51
|
+
*/
|
|
7
52
|
declare function ifFalse<T>(value: boolean, fn: () => T): Maybe<T>;
|
|
53
|
+
/**
|
|
54
|
+
* Matches a pair of Maybe values against the provided cases, depending on which of them are defined.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
*
|
|
58
|
+
* ```ts
|
|
59
|
+
* const a: Maybe<number> = 5;
|
|
60
|
+
* const b: Maybe<string> = undefined;
|
|
61
|
+
*
|
|
62
|
+
* const result = matchPair([a, b], {
|
|
63
|
+
* neither: () => 'neither',
|
|
64
|
+
* a: (a) => `a is ${a}`,
|
|
65
|
+
* b: (b) => `b is ${b}`,
|
|
66
|
+
* both: (a, b) => `both are ${a} and ${b}`,
|
|
67
|
+
* });
|
|
68
|
+
*
|
|
69
|
+
* console.log(result); // Output: "a is 5"
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
8
72
|
declare function matchPair<A, B, R>([a, b]: [Maybe<A>, Maybe<B>], cases: {
|
|
9
73
|
neither: () => R;
|
|
10
74
|
a: (a: A) => R;
|
package/dist/maybe.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"maybe.d.mts","names":[],"sources":["../src/maybe.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"maybe.d.mts","names":[],"sources":["../src/maybe.ts"],"mappings":";;;;KAGY,MAAM,KAAK;;;;;;;;;;;;;;iBAeP,SAAS,GAAG,GAAG,OAAO,MAAM,IAAI,KAAK,OAAO,MAAM,IAAI,MAAM;;;;;;;;;;;;;;iBAiB5D,UAAU,GAAG,OAAO,MAAM,KAAK,SAAS;;;;;;;;;;;iBAcxC,aAAa,GAAG,OAAO,MAAM,MAAM,MAAM,MAAM;;;;iBAO/C,OAAO,GAAG,gBAAgB,UAAU,IAAI,MAAM;;;;iBAO9C,QAAQ,GAAG,gBAAgB,UAAU,IAAI,MAAM;;;;;;;;;;;;;;;;;;;;iBAuB/C,UAAU,GAAG,GAAG,IAC7B,GAAG,KAAK,MAAM,IAAI,MAAM,KACzB;EACE,eAAe;EACf,IAAI,GAAG,MAAM;EACb,IAAI,GAAG,MAAM;EACb,OAAO,GAAG,GAAG,GAAG,MAAM;IAEvB"}
|
package/dist/maybe.mjs
CHANGED
|
@@ -1,19 +1,80 @@
|
|
|
1
1
|
//#region src/maybe.ts
|
|
2
|
+
/**
|
|
3
|
+
* Maps the value if it is defined, performs no operation if it is undefined.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* const value: Maybe<number> = 5;
|
|
9
|
+
* const result: Maybe<string> = mapMaybe(value, (v) => `Value is ${v}`); // "Value is 5"
|
|
10
|
+
*
|
|
11
|
+
* const undefinedValue: Maybe<number> = undefined;
|
|
12
|
+
* const undefinedResult: Maybe<string> = mapMaybe(undefinedValue, (v) => `Value is ${v}`); // undefined
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
2
15
|
function mapMaybe(value, fn) {
|
|
3
16
|
return value === void 0 ? void 0 : fn(value);
|
|
4
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Returns true if the value is defined, false if it is undefined.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
*
|
|
23
|
+
* ```ts
|
|
24
|
+
* const definedValue: Maybe<number> = 5;
|
|
25
|
+
*
|
|
26
|
+
* if (isDefined(definedValue)) {
|
|
27
|
+
* console.log(definedValue + 1); // Output: 6
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
5
31
|
function isDefined(value) {
|
|
6
32
|
return value !== void 0;
|
|
7
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Flattens a nested Maybe into a single Maybe.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
*
|
|
39
|
+
* ```ts
|
|
40
|
+
* const nested: Maybe<Maybe<number>> = 5;
|
|
41
|
+
* const flattened: Maybe<number> = flattenMaybe(nested); // 5
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
8
44
|
function flattenMaybe(value) {
|
|
9
45
|
return mapMaybe(value, (v) => v);
|
|
10
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Returns the result of the provided function if the value is true, undefined otherwise.
|
|
49
|
+
*/
|
|
11
50
|
function ifTrue(value, fn) {
|
|
12
51
|
return value ? fn() : void 0;
|
|
13
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Returns the result of the provided function if the value is false, undefined otherwise.
|
|
55
|
+
*/
|
|
14
56
|
function ifFalse(value, fn) {
|
|
15
57
|
return !value ? fn() : void 0;
|
|
16
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Matches a pair of Maybe values against the provided cases, depending on which of them are defined.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
*
|
|
64
|
+
* ```ts
|
|
65
|
+
* const a: Maybe<number> = 5;
|
|
66
|
+
* const b: Maybe<string> = undefined;
|
|
67
|
+
*
|
|
68
|
+
* const result = matchPair([a, b], {
|
|
69
|
+
* neither: () => 'neither',
|
|
70
|
+
* a: (a) => `a is ${a}`,
|
|
71
|
+
* b: (b) => `b is ${b}`,
|
|
72
|
+
* both: (a, b) => `both are ${a} and ${b}`,
|
|
73
|
+
* });
|
|
74
|
+
*
|
|
75
|
+
* console.log(result); // Output: "a is 5"
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
17
78
|
function matchPair([a, b], cases) {
|
|
18
79
|
if (!isDefined(a)) {
|
|
19
80
|
if (!isDefined(b)) return cases.neither();
|
package/dist/maybe.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"maybe.mjs","names":[],"sources":["../src/maybe.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"maybe.mjs","names":[],"sources":["../src/maybe.ts"],"sourcesContent":["/**\n * Represents a value that may be absent.\n */\nexport type Maybe<T> = T | undefined;\n\n/**\n * Maps the value if it is defined, performs no operation if it is undefined.\n *\n * @example\n *\n * ```ts\n * const value: Maybe<number> = 5;\n * const result: Maybe<string> = mapMaybe(value, (v) => `Value is ${v}`); // \"Value is 5\"\n *\n * const undefinedValue: Maybe<number> = undefined;\n * const undefinedResult: Maybe<string> = mapMaybe(undefinedValue, (v) => `Value is ${v}`); // undefined\n * ```\n */\nexport function mapMaybe<T, U>(value: Maybe<T>, fn: (value: T) => U): Maybe<U> {\n return value === undefined ? undefined : fn(value);\n}\n\n/**\n * Returns true if the value is defined, false if it is undefined.\n *\n * @example\n *\n * ```ts\n * const definedValue: Maybe<number> = 5;\n *\n * if (isDefined(definedValue)) {\n * console.log(definedValue + 1); // Output: 6\n * }\n * ```\n */\nexport function isDefined<T>(value: Maybe<T>): value is T {\n return value !== undefined;\n}\n\n/**\n * Flattens a nested Maybe into a single Maybe.\n *\n * @example\n *\n * ```ts\n * const nested: Maybe<Maybe<number>> = 5;\n * const flattened: Maybe<number> = flattenMaybe(nested); // 5\n * ```\n */\nexport function flattenMaybe<T>(value: Maybe<Maybe<T>>): Maybe<T> {\n return mapMaybe(value, (v) => v);\n}\n\n/**\n * Returns the result of the provided function if the value is true, undefined otherwise.\n */\nexport function ifTrue<T>(value: boolean, fn: () => T): Maybe<T> {\n return value ? fn() : undefined;\n}\n\n/**\n * Returns the result of the provided function if the value is false, undefined otherwise.\n */\nexport function ifFalse<T>(value: boolean, fn: () => T): Maybe<T> {\n return !value ? fn() : undefined;\n}\n\n/**\n * Matches a pair of Maybe values against the provided cases, depending on which of them are defined.\n *\n * @example\n *\n * ```ts\n * const a: Maybe<number> = 5;\n * const b: Maybe<string> = undefined;\n *\n * const result = matchPair([a, b], {\n * neither: () => 'neither',\n * a: (a) => `a is ${a}`,\n * b: (b) => `b is ${b}`,\n * both: (a, b) => `both are ${a} and ${b}`,\n * });\n *\n * console.log(result); // Output: \"a is 5\"\n * ```\n */\nexport function matchPair<A, B, R>(\n [a, b]: [Maybe<A>, Maybe<B>],\n cases: {\n neither: () => R;\n a: (a: A) => R;\n b: (b: B) => R;\n both: (a: A, b: B) => R;\n },\n): R {\n if (!isDefined(a)) {\n if (!isDefined(b)) {\n return cases.neither();\n }\n\n return cases.b(b);\n }\n\n if (!isDefined(b)) {\n return cases.a(a);\n }\n\n return cases.both(a, b);\n}\n"],"mappings":";;;;;;;;;;;;;;AAkBA,SAAgB,SAAe,OAAiB,IAA+B;CAC7E,OAAO,UAAU,SAAY,SAAY,GAAG,KAAK;AACnD;;;;;;;;;;;;;;AAeA,SAAgB,UAAa,OAA6B;CACxD,OAAO,UAAU;AACnB;;;;;;;;;;;AAYA,SAAgB,aAAgB,OAAkC;CAChE,OAAO,SAAS,QAAQ,MAAM,CAAC;AACjC;;;;AAKA,SAAgB,OAAU,OAAgB,IAAuB;CAC/D,OAAO,QAAQ,GAAG,IAAI;AACxB;;;;AAKA,SAAgB,QAAW,OAAgB,IAAuB;CAChE,OAAO,CAAC,QAAQ,GAAG,IAAI;AACzB;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,UACd,CAAC,GAAG,IACJ,OAMG;CACH,IAAI,CAAC,UAAU,CAAC,GAAG;EACjB,IAAI,CAAC,UAAU,CAAC,GACd,OAAO,MAAM,QAAQ;EAGvB,OAAO,MAAM,EAAE,CAAC;CAClB;CAEA,IAAI,CAAC,UAAU,CAAC,GACd,OAAO,MAAM,EAAE,CAAC;CAGlB,OAAO,MAAM,KAAK,GAAG,CAAC;AACxB"}
|
package/package.json
CHANGED
package/src/either.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { isDefined } from './maybe.js';
|
|
|
7
7
|
// And conversely, xxx implementations in EitherP all look like:
|
|
8
8
|
// new EitherP(this.value.then(e => e.xxx(...)))
|
|
9
9
|
|
|
10
|
-
abstract class EitherBase<L, R> {
|
|
10
|
+
export abstract class EitherBase<L, R> {
|
|
11
11
|
/**
|
|
12
12
|
* Maps the value of this Either if it is a Right, performs no operation if this is a Left.
|
|
13
13
|
*/
|
|
@@ -15,6 +15,9 @@ abstract class EitherBase<L, R> {
|
|
|
15
15
|
return this.flatMap((value) => Either.right(fn(value)));
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
20
|
+
*/
|
|
18
21
|
mapAsync<R2>(fn: (t: R) => Promise<R2>): EitherP<L, R2> {
|
|
19
22
|
return EitherP.fromPromise(toEitherPromise(this)).mapAsync(fn);
|
|
20
23
|
}
|
|
@@ -29,6 +32,9 @@ abstract class EitherBase<L, R> {
|
|
|
29
32
|
);
|
|
30
33
|
}
|
|
31
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Flat maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
|
|
37
|
+
*/
|
|
32
38
|
leftFlatMapAsync<L2, R2>(fn: (t: L) => PromiseLike<Either<L2, R2>>): EitherP<L2, R | R2> {
|
|
33
39
|
return EitherP.fromPromise(toEitherPromise(this)).leftFlatMapAsync(fn);
|
|
34
40
|
}
|
|
@@ -43,6 +49,9 @@ abstract class EitherBase<L, R> {
|
|
|
43
49
|
);
|
|
44
50
|
}
|
|
45
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
|
|
54
|
+
*/
|
|
46
55
|
leftMapAsync<L2>(fn: (t: L) => Promise<L2>): EitherP<L2, R> {
|
|
47
56
|
return EitherP.fromPromise(toEitherPromise(this)).leftMapAsync(fn);
|
|
48
57
|
}
|
|
@@ -57,6 +66,9 @@ abstract class EitherBase<L, R> {
|
|
|
57
66
|
);
|
|
58
67
|
}
|
|
59
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either, asynchronously.
|
|
71
|
+
*/
|
|
60
72
|
bimapAsync<L2, R2>(
|
|
61
73
|
leftFn: (l: L) => Promise<L2>,
|
|
62
74
|
rightFn: (r: R) => Promise<R2>,
|
|
@@ -74,6 +86,9 @@ abstract class EitherBase<L, R> {
|
|
|
74
86
|
});
|
|
75
87
|
}
|
|
76
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
91
|
+
*/
|
|
77
92
|
tapAsync(fn: (t: R) => Promise<void>): EitherP<L, R> {
|
|
78
93
|
return EitherP.fromPromise(toEitherPromise(this)).tapAsync(fn);
|
|
79
94
|
}
|
|
@@ -86,6 +101,10 @@ abstract class EitherBase<L, R> {
|
|
|
86
101
|
return this.flatMap((value) => fn(value).map(() => value));
|
|
87
102
|
}
|
|
88
103
|
|
|
104
|
+
/**
|
|
105
|
+
* Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
106
|
+
* If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.
|
|
107
|
+
*/
|
|
89
108
|
flatTapAsync<L2>(fn: (t: R) => PromiseLike<Either<L2, void>>): EitherP<L | L2, R> {
|
|
90
109
|
return EitherP.fromPromise(toEitherPromise(this)).flatTapAsync(fn);
|
|
91
110
|
}
|
|
@@ -100,6 +119,9 @@ abstract class EitherBase<L, R> {
|
|
|
100
119
|
);
|
|
101
120
|
}
|
|
102
121
|
|
|
122
|
+
/**
|
|
123
|
+
* Flat maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
124
|
+
*/
|
|
103
125
|
flatMapAsync<L2, R2>(fn: (t: R) => PromiseLike<Either<L2, R2>>): EitherP<L | L2, R2> {
|
|
104
126
|
return EitherP.fromPromise(toEitherPromise(this)).flatMapAsync(fn);
|
|
105
127
|
}
|
|
@@ -149,20 +171,16 @@ abstract class EitherBase<L, R> {
|
|
|
149
171
|
* Gets the right value if this is a Right or undefined if it's a Left.
|
|
150
172
|
*/
|
|
151
173
|
get(): Maybe<R> {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
(r) => r,
|
|
155
|
-
);
|
|
174
|
+
// Overridden in Right#get
|
|
175
|
+
return undefined;
|
|
156
176
|
}
|
|
157
177
|
|
|
158
178
|
/**
|
|
159
179
|
* Returns the left value if this is a Left or undefined if it's a Right.
|
|
160
180
|
*/
|
|
161
181
|
getLeft(): Maybe<L> {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
() => undefined,
|
|
165
|
-
);
|
|
182
|
+
// Overridden in Left#getLeft
|
|
183
|
+
return undefined;
|
|
166
184
|
}
|
|
167
185
|
|
|
168
186
|
/**
|
|
@@ -176,8 +194,8 @@ abstract class EitherBase<L, R> {
|
|
|
176
194
|
}
|
|
177
195
|
}
|
|
178
196
|
|
|
179
|
-
// EitherBase is abstract with only Left/Right as concrete subclasses; the cast is always valid.
|
|
180
197
|
function toEitherPromise<L, R>(e: EitherBase<L, R>): Promise<Either<L, R>> {
|
|
198
|
+
// EitherBase is abstract with only Left/Right as concrete subclasses; the cast is always valid.
|
|
181
199
|
return Promise.resolve(e as unknown as Either<L, R>);
|
|
182
200
|
}
|
|
183
201
|
|
|
@@ -193,6 +211,14 @@ export class Left<L> extends EitherBase<L, never> {
|
|
|
193
211
|
override getLeft(): L {
|
|
194
212
|
return this.value;
|
|
195
213
|
}
|
|
214
|
+
|
|
215
|
+
override toString(): string {
|
|
216
|
+
return `Left(${String(this.value)})`;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
get [Symbol.toStringTag](): string {
|
|
220
|
+
return 'Left';
|
|
221
|
+
}
|
|
196
222
|
}
|
|
197
223
|
|
|
198
224
|
export class Right<R> extends EitherBase<never, R> {
|
|
@@ -207,11 +233,17 @@ export class Right<R> extends EitherBase<never, R> {
|
|
|
207
233
|
override get(): R {
|
|
208
234
|
return this.value;
|
|
209
235
|
}
|
|
236
|
+
|
|
237
|
+
override toString(): string {
|
|
238
|
+
return `Right(${String(this.value)})`;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
get [Symbol.toStringTag](): string {
|
|
242
|
+
return 'Right';
|
|
243
|
+
}
|
|
210
244
|
}
|
|
211
245
|
|
|
212
246
|
/**
|
|
213
|
-
* Mimics the [Cats Either[L, R]](https://typelevel.org/cats/datatypes/either.html) type.
|
|
214
|
-
*
|
|
215
247
|
* Either<L, R> is a union of Left<L> and Right<R>, so narrowing works in both directions:
|
|
216
248
|
*
|
|
217
249
|
* ```ts
|
|
@@ -241,17 +273,28 @@ export namespace Either {
|
|
|
241
273
|
return new Right(value);
|
|
242
274
|
}
|
|
243
275
|
|
|
276
|
+
/**
|
|
277
|
+
* Creates a Right Either from a Maybe if it is defined, or a Left Either from the result of the provided function otherwise.
|
|
278
|
+
*/
|
|
244
279
|
export function fromMaybe<L, R>(value: Maybe<R>, leftValue: () => L): Either<L, R> {
|
|
245
280
|
return isDefined(value) ? Either.right(value) : Either.left(leftValue());
|
|
246
281
|
}
|
|
247
282
|
|
|
283
|
+
/**
|
|
284
|
+
* Creates a Right Either from the result of `rightFn` if `bool` is true, or a Left Either from the result of `leftFn` otherwise.
|
|
285
|
+
*/
|
|
248
286
|
export function cond<L, R>(bool: boolean, leftFn: () => L, rightFn: () => R): Either<L, R> {
|
|
249
287
|
return bool ? Either.right(rightFn()) : Either.left(leftFn());
|
|
250
288
|
}
|
|
251
289
|
}
|
|
252
290
|
|
|
253
291
|
/**
|
|
254
|
-
*
|
|
292
|
+
* Asynchronous version of @{link Either}, allowing for asynchronous operations on the values of the Either.
|
|
293
|
+
*
|
|
294
|
+
* ```ts
|
|
295
|
+
* declare const e: EitherP<string, number>;
|
|
296
|
+
*
|
|
297
|
+
* const result = await e.get(); // result is of type Maybe<number>
|
|
255
298
|
*/
|
|
256
299
|
export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
|
|
257
300
|
private constructor(private readonly value: PromiseLike<Either<L, R>>) {}
|
|
@@ -263,6 +306,9 @@ export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
|
|
|
263
306
|
return new EitherP(this.value.then((e) => e.map(fn)));
|
|
264
307
|
}
|
|
265
308
|
|
|
309
|
+
/**
|
|
310
|
+
* Maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
311
|
+
*/
|
|
266
312
|
mapAsync<R2>(fn: (t: R) => Promise<R2>): EitherP<L, R2> {
|
|
267
313
|
return this.flatMapAsync(async (value) => Either.right(await fn(value)));
|
|
268
314
|
}
|
|
@@ -274,6 +320,9 @@ export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
|
|
|
274
320
|
return new EitherP(this.value.then((e) => e.leftMap(fn)));
|
|
275
321
|
}
|
|
276
322
|
|
|
323
|
+
/**
|
|
324
|
+
* Maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
|
|
325
|
+
*/
|
|
277
326
|
leftMapAsync<L2>(fn: (t: L) => Promise<L2>): EitherP<L2, R> {
|
|
278
327
|
return new EitherP(
|
|
279
328
|
this.value.then(
|
|
@@ -293,6 +342,9 @@ export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
|
|
|
293
342
|
return new EitherP(this.value.then((e) => e.leftFlatMap(fn)));
|
|
294
343
|
}
|
|
295
344
|
|
|
345
|
+
/**
|
|
346
|
+
* Flat maps the value of this Either if it is a Left, performs no operation if this is a Right, asynchronously.
|
|
347
|
+
*/
|
|
296
348
|
leftFlatMapAsync<L2, R2>(fn: (t: L) => PromiseLike<Either<L2, R2>>): EitherP<L2, R | R2> {
|
|
297
349
|
return new EitherP(
|
|
298
350
|
this.value.then<Either<L2, R | R2>>(
|
|
@@ -312,6 +364,9 @@ export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
|
|
|
312
364
|
return new EitherP(this.value.then((e) => e.bimap(leftFn, rightFn)));
|
|
313
365
|
}
|
|
314
366
|
|
|
367
|
+
/**
|
|
368
|
+
* Applies the provided functions to the value of this Either, depending on whether it is a Right or a Left and returns a new Either, asynchronously.
|
|
369
|
+
*/
|
|
315
370
|
bimapAsync<L2, R2>(
|
|
316
371
|
leftFn: (l: L) => Promise<L2>,
|
|
317
372
|
rightFn: (r: R) => Promise<R2>,
|
|
@@ -334,6 +389,9 @@ export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
|
|
|
334
389
|
return new EitherP(this.value.then((e) => e.tap(fn)));
|
|
335
390
|
}
|
|
336
391
|
|
|
392
|
+
/**
|
|
393
|
+
* Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
394
|
+
*/
|
|
337
395
|
tapAsync(fn: (t: R) => Promise<void>): EitherP<L, R> {
|
|
338
396
|
return this.flatMapAsync(async (value) => {
|
|
339
397
|
await fn(value);
|
|
@@ -349,6 +407,10 @@ export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
|
|
|
349
407
|
return new EitherP(this.value.then((e) => e.flatTap(fn)));
|
|
350
408
|
}
|
|
351
409
|
|
|
410
|
+
/**
|
|
411
|
+
* Runs the provided function with the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
412
|
+
* If the result of the function is a Left, it will be returned, otherwise the original Right value will be returned.
|
|
413
|
+
*/
|
|
352
414
|
flatTapAsync<L2>(fn: (t: R) => PromiseLike<Either<L2, void>>): EitherP<L | L2, R> {
|
|
353
415
|
return this.flatMapAsync(async (value) => (await fn(value)).map(() => value));
|
|
354
416
|
}
|
|
@@ -360,6 +422,9 @@ export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
|
|
|
360
422
|
return new EitherP(this.value.then((e) => e.flatMap(fn)));
|
|
361
423
|
}
|
|
362
424
|
|
|
425
|
+
/**
|
|
426
|
+
* Flat maps the value of this Either if it is a Right, performs no operation if this is a Left, asynchronously.
|
|
427
|
+
*/
|
|
363
428
|
flatMapAsync<L2, R2>(fn: (t: R) => PromiseLike<Either<L2, R2>>): EitherP<L | L2, R2> {
|
|
364
429
|
return new EitherP(
|
|
365
430
|
this.value.then<Either<L | L2, R2>>((e) =>
|
|
@@ -443,6 +508,9 @@ export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
|
|
|
443
508
|
return new EitherP(value.then((v) => Either.right(v)));
|
|
444
509
|
}
|
|
445
510
|
|
|
511
|
+
/**
|
|
512
|
+
* Creates a Right EitherP from a Promise of a Maybe if it resolves to a defined value, or a Left EitherP from the result of the provided function otherwise.
|
|
513
|
+
*/
|
|
446
514
|
static fromMaybe<L, R>(value: Promise<Maybe<R>>, leftValue: () => Promise<L>): EitherP<L, R> {
|
|
447
515
|
return new EitherP(
|
|
448
516
|
value.then(async (v) => (isDefined(v) ? Either.right(v) : Either.left(await leftValue()))),
|
|
@@ -450,16 +518,15 @@ export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
|
|
|
450
518
|
}
|
|
451
519
|
|
|
452
520
|
/**
|
|
453
|
-
*
|
|
521
|
+
* Creates a new EitherP from a Promise of an Either.
|
|
454
522
|
*/
|
|
455
|
-
static fromEither<L, R>(either: PromiseLike<Either<L, R>>): EitherP<L, R> {
|
|
456
|
-
return new EitherP(either);
|
|
457
|
-
}
|
|
458
|
-
|
|
459
523
|
static fromPromise<L, R>(either: PromiseLike<Either<L, R>>): EitherP<L, R> {
|
|
460
524
|
return new EitherP(either);
|
|
461
525
|
}
|
|
462
526
|
|
|
527
|
+
/**
|
|
528
|
+
* Creates a new Right EitherP if the provided Promise resolves to true, or a new Left EitherP otherwise.
|
|
529
|
+
*/
|
|
463
530
|
static cond<L, R>(
|
|
464
531
|
bool: Promise<boolean>,
|
|
465
532
|
leftFn: () => Promise<L>,
|
|
@@ -470,6 +537,9 @@ export class EitherP<L, R> implements PromiseLike<Either<L, R>> {
|
|
|
470
537
|
);
|
|
471
538
|
}
|
|
472
539
|
|
|
540
|
+
/**
|
|
541
|
+
* Resolves this EitherP to its underlying Either, allowing `await` usage on EitherP instances.
|
|
542
|
+
*/
|
|
473
543
|
// oxlint-disable-next-line unicorn/no-thenable -- Deliberately implementing PromiseLike to allow for `await` usage on EitherP instances.
|
|
474
544
|
then<U>(onfulfilled?: (value: Either<L, R>) => U | PromiseLike<U>): PromiseLike<U> {
|
|
475
545
|
return this.value.then(onfulfilled);
|
package/src/maybe.ts
CHANGED
|
@@ -1,25 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a value that may be absent.
|
|
3
|
+
*/
|
|
1
4
|
export type Maybe<T> = T | undefined;
|
|
2
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Maps the value if it is defined, performs no operation if it is undefined.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
*
|
|
11
|
+
* ```ts
|
|
12
|
+
* const value: Maybe<number> = 5;
|
|
13
|
+
* const result: Maybe<string> = mapMaybe(value, (v) => `Value is ${v}`); // "Value is 5"
|
|
14
|
+
*
|
|
15
|
+
* const undefinedValue: Maybe<number> = undefined;
|
|
16
|
+
* const undefinedResult: Maybe<string> = mapMaybe(undefinedValue, (v) => `Value is ${v}`); // undefined
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
3
19
|
export function mapMaybe<T, U>(value: Maybe<T>, fn: (value: T) => U): Maybe<U> {
|
|
4
20
|
return value === undefined ? undefined : fn(value);
|
|
5
21
|
}
|
|
6
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Returns true if the value is defined, false if it is undefined.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
*
|
|
28
|
+
* ```ts
|
|
29
|
+
* const definedValue: Maybe<number> = 5;
|
|
30
|
+
*
|
|
31
|
+
* if (isDefined(definedValue)) {
|
|
32
|
+
* console.log(definedValue + 1); // Output: 6
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
7
36
|
export function isDefined<T>(value: Maybe<T>): value is T {
|
|
8
37
|
return value !== undefined;
|
|
9
38
|
}
|
|
10
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Flattens a nested Maybe into a single Maybe.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
*
|
|
45
|
+
* ```ts
|
|
46
|
+
* const nested: Maybe<Maybe<number>> = 5;
|
|
47
|
+
* const flattened: Maybe<number> = flattenMaybe(nested); // 5
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
11
50
|
export function flattenMaybe<T>(value: Maybe<Maybe<T>>): Maybe<T> {
|
|
12
51
|
return mapMaybe(value, (v) => v);
|
|
13
52
|
}
|
|
14
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Returns the result of the provided function if the value is true, undefined otherwise.
|
|
56
|
+
*/
|
|
15
57
|
export function ifTrue<T>(value: boolean, fn: () => T): Maybe<T> {
|
|
16
58
|
return value ? fn() : undefined;
|
|
17
59
|
}
|
|
18
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Returns the result of the provided function if the value is false, undefined otherwise.
|
|
63
|
+
*/
|
|
19
64
|
export function ifFalse<T>(value: boolean, fn: () => T): Maybe<T> {
|
|
20
65
|
return !value ? fn() : undefined;
|
|
21
66
|
}
|
|
22
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Matches a pair of Maybe values against the provided cases, depending on which of them are defined.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
*
|
|
73
|
+
* ```ts
|
|
74
|
+
* const a: Maybe<number> = 5;
|
|
75
|
+
* const b: Maybe<string> = undefined;
|
|
76
|
+
*
|
|
77
|
+
* const result = matchPair([a, b], {
|
|
78
|
+
* neither: () => 'neither',
|
|
79
|
+
* a: (a) => `a is ${a}`,
|
|
80
|
+
* b: (b) => `b is ${b}`,
|
|
81
|
+
* both: (a, b) => `both are ${a} and ${b}`,
|
|
82
|
+
* });
|
|
83
|
+
*
|
|
84
|
+
* console.log(result); // Output: "a is 5"
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
23
87
|
export function matchPair<A, B, R>(
|
|
24
88
|
[a, b]: [Maybe<A>, Maybe<B>],
|
|
25
89
|
cases: {
|