@nunofyobiz/effect-extras 2.1.0 → 3.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/README.md +2 -1
- package/dist/ArrayX.d.ts +0 -34
- package/dist/ArrayX.d.ts.map +1 -1
- package/dist/ArrayX.js +4 -58
- package/dist/ArrayX.js.map +1 -1
- package/dist/InclusiveOr.d.ts +1123 -0
- package/dist/InclusiveOr.d.ts.map +1 -0
- package/dist/InclusiveOr.js +1074 -0
- package/dist/InclusiveOr.js.map +1 -0
- package/dist/NonNullableX.d.ts.map +1 -1
- package/dist/NonNullableX.js +5 -0
- package/dist/NonNullableX.js.map +1 -1
- package/dist/OptionX.d.ts +8 -2
- package/dist/OptionX.d.ts.map +1 -1
- package/dist/OptionX.js +7 -1
- package/dist/OptionX.js.map +1 -1
- package/dist/PredicateX.d.ts +32 -0
- package/dist/PredicateX.d.ts.map +1 -1
- package/dist/PredicateX.js +38 -0
- package/dist/PredicateX.js.map +1 -1
- package/dist/RecordX.d.ts +128 -1
- package/dist/RecordX.d.ts.map +1 -1
- package/dist/RecordX.js +162 -1
- package/dist/RecordX.js.map +1 -1
- package/dist/StringX.d.ts +61 -0
- package/dist/StringX.d.ts.map +1 -1
- package/dist/StringX.js +68 -0
- package/dist/StringX.js.map +1 -1
- package/dist/WarnResult.d.ts +115 -70
- package/dist/WarnResult.d.ts.map +1 -1
- package/dist/WarnResult.js +141 -210
- package/dist/WarnResult.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/ArrayX.ts +4 -86
- package/src/InclusiveOr.ts +1255 -0
- package/src/NonNullableX.ts +5 -0
- package/src/OptionX.ts +8 -2
- package/src/PredicateX.ts +41 -0
- package/src/RecordX.ts +183 -1
- package/src/StringX.ts +113 -0
- package/src/WarnResult.ts +297 -227
- package/src/index.ts +1 -0
|
@@ -0,0 +1,1123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `InclusiveOr` data type — an inclusive-or carrying a `left`, a `right`, or both at once.
|
|
3
|
+
*
|
|
4
|
+
* @since 0.0.0
|
|
5
|
+
*/
|
|
6
|
+
import { Data, Effect, Option } from "effect";
|
|
7
|
+
/**
|
|
8
|
+
* A value carrying a left `L`, a right `R`, or both at once — the data type for
|
|
9
|
+
* an "inclusive or".
|
|
10
|
+
*
|
|
11
|
+
* Where `Result<R, L>` models an exclusive choice (success _or_ failure),
|
|
12
|
+
* `InclusiveOr` adds the third case where both sides are present. It is a tagged enum
|
|
13
|
+
* with three constructors: `LeftOnly` (only `left`), `RightOnly` (only `right`),
|
|
14
|
+
* and `LeftAndRight` (both). Reach for it when an operation can produce partial
|
|
15
|
+
* results — e.g. a parse that yields a value _and_ a list of warnings.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
20
|
+
*
|
|
21
|
+
* const both: InclusiveOr.InclusiveOr<number, string> = InclusiveOr.LeftAndRight({
|
|
22
|
+
* left: 1,
|
|
23
|
+
* right: "a"
|
|
24
|
+
* })
|
|
25
|
+
*
|
|
26
|
+
* assert.deepStrictEqual(both._tag, "LeftAndRight")
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @category models
|
|
30
|
+
* @since 0.0.0
|
|
31
|
+
*/
|
|
32
|
+
export type InclusiveOr<L, R> = Data.TaggedEnum<{
|
|
33
|
+
LeftOnly: {
|
|
34
|
+
readonly left: L;
|
|
35
|
+
};
|
|
36
|
+
RightOnly: {
|
|
37
|
+
readonly right: R;
|
|
38
|
+
};
|
|
39
|
+
LeftAndRight: {
|
|
40
|
+
readonly left: L;
|
|
41
|
+
readonly right: R;
|
|
42
|
+
};
|
|
43
|
+
}>;
|
|
44
|
+
/**
|
|
45
|
+
* The `LeftOnly` member of `InclusiveOr` — a value that carries only a `left` and no
|
|
46
|
+
* `right`.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
51
|
+
*
|
|
52
|
+
* const value: InclusiveOr.LeftOnly<number> = InclusiveOr.LeftOnly({ left: 1 })
|
|
53
|
+
*
|
|
54
|
+
* assert.deepStrictEqual(value.left, 1)
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* @category models
|
|
58
|
+
* @since 0.0.0
|
|
59
|
+
*/
|
|
60
|
+
export type LeftOnly<L> = InclusiveOr<L, never> & {
|
|
61
|
+
_tag: "LeftOnly";
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* The `RightOnly` member of `InclusiveOr` — a value that carries only a `right` and no
|
|
65
|
+
* `left`.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
70
|
+
*
|
|
71
|
+
* const value: InclusiveOr.RightOnly<string> = InclusiveOr.RightOnly({ right: "a" })
|
|
72
|
+
*
|
|
73
|
+
* assert.deepStrictEqual(value.right, "a")
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* @category models
|
|
77
|
+
* @since 0.0.0
|
|
78
|
+
*/
|
|
79
|
+
export type RightOnly<R> = InclusiveOr<never, R> & {
|
|
80
|
+
_tag: "RightOnly";
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* The `LeftAndRight` member of `InclusiveOr` — a value that carries both a `left` and a
|
|
84
|
+
* `right`.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
89
|
+
*
|
|
90
|
+
* const value: InclusiveOr.LeftAndRight<number, string> = InclusiveOr.LeftAndRight({
|
|
91
|
+
* left: 1,
|
|
92
|
+
* right: "a"
|
|
93
|
+
* })
|
|
94
|
+
*
|
|
95
|
+
* assert.deepStrictEqual(value, { _tag: "LeftAndRight", left: 1, right: "a" })
|
|
96
|
+
* ```
|
|
97
|
+
*
|
|
98
|
+
* @category models
|
|
99
|
+
* @since 0.0.0
|
|
100
|
+
*/
|
|
101
|
+
export type LeftAndRight<L, R> = InclusiveOr<L, R> & {
|
|
102
|
+
_tag: "LeftAndRight";
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Any `InclusiveOr` that is guaranteed to carry a `left` — either `LeftOnly` or
|
|
106
|
+
* `LeftAndRight`.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
111
|
+
*
|
|
112
|
+
* const value: InclusiveOr.WithLeft<number, string> = InclusiveOr.LeftOnly({ left: 1 })
|
|
113
|
+
*
|
|
114
|
+
* assert.deepStrictEqual(value.left, 1)
|
|
115
|
+
* ```
|
|
116
|
+
*
|
|
117
|
+
* @category models
|
|
118
|
+
* @since 0.0.0
|
|
119
|
+
*/
|
|
120
|
+
export type WithLeft<L, R> = LeftOnly<L> | LeftAndRight<L, R>;
|
|
121
|
+
/**
|
|
122
|
+
* Any `InclusiveOr` that is guaranteed to carry a `right` — either `RightOnly` or
|
|
123
|
+
* `LeftAndRight`.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
128
|
+
*
|
|
129
|
+
* const value: InclusiveOr.WithRight<number, string> = InclusiveOr.RightOnly({ right: "a" })
|
|
130
|
+
*
|
|
131
|
+
* assert.deepStrictEqual(value.right, "a")
|
|
132
|
+
* ```
|
|
133
|
+
*
|
|
134
|
+
* @category models
|
|
135
|
+
* @since 0.0.0
|
|
136
|
+
*/
|
|
137
|
+
export type WithRight<L, R> = RightOnly<R> | LeftAndRight<L, R>;
|
|
138
|
+
/**
|
|
139
|
+
* Constructs a `LeftOnly` — an `InclusiveOr` that carries only a `left`.
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```ts
|
|
143
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
144
|
+
*
|
|
145
|
+
* const value = InclusiveOr.LeftOnly({ left: 1 })
|
|
146
|
+
*
|
|
147
|
+
* assert.deepStrictEqual(value._tag, "LeftOnly")
|
|
148
|
+
* assert.deepStrictEqual(value.left, 1)
|
|
149
|
+
* ```
|
|
150
|
+
*
|
|
151
|
+
* @category constructors
|
|
152
|
+
* @since 0.0.0
|
|
153
|
+
*/
|
|
154
|
+
export declare const LeftOnly: <A, B>(args: {
|
|
155
|
+
readonly left: A;
|
|
156
|
+
}) => {
|
|
157
|
+
readonly _tag: "LeftOnly";
|
|
158
|
+
readonly left: A;
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* Constructs a `RightOnly` — an `InclusiveOr` that carries only a `right`.
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```ts
|
|
165
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
166
|
+
*
|
|
167
|
+
* const value = InclusiveOr.RightOnly({ right: "a" })
|
|
168
|
+
*
|
|
169
|
+
* assert.deepStrictEqual(value._tag, "RightOnly")
|
|
170
|
+
* assert.deepStrictEqual(value.right, "a")
|
|
171
|
+
* ```
|
|
172
|
+
*
|
|
173
|
+
* @category constructors
|
|
174
|
+
* @since 0.0.0
|
|
175
|
+
*/
|
|
176
|
+
export declare const RightOnly: <A, B>(args: {
|
|
177
|
+
readonly right: B;
|
|
178
|
+
}) => {
|
|
179
|
+
readonly _tag: "RightOnly";
|
|
180
|
+
readonly right: B;
|
|
181
|
+
};
|
|
182
|
+
/**
|
|
183
|
+
* Constructs a `LeftAndRight` — an `InclusiveOr` that carries both a `left` and a
|
|
184
|
+
* `right`.
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```ts
|
|
188
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
189
|
+
*
|
|
190
|
+
* const value = InclusiveOr.LeftAndRight({ left: 1, right: "a" })
|
|
191
|
+
*
|
|
192
|
+
* assert.deepStrictEqual(value._tag, "LeftAndRight")
|
|
193
|
+
* assert.deepStrictEqual(value.left, 1)
|
|
194
|
+
* assert.deepStrictEqual(value.right, "a")
|
|
195
|
+
* ```
|
|
196
|
+
*
|
|
197
|
+
* @category constructors
|
|
198
|
+
* @since 0.0.0
|
|
199
|
+
*/
|
|
200
|
+
export declare const LeftAndRight: <A, B>(args: {
|
|
201
|
+
readonly left: A;
|
|
202
|
+
readonly right: B;
|
|
203
|
+
}) => {
|
|
204
|
+
readonly _tag: "LeftAndRight";
|
|
205
|
+
readonly left: A;
|
|
206
|
+
readonly right: B;
|
|
207
|
+
};
|
|
208
|
+
/**
|
|
209
|
+
* Builds per-tag refinements for `InclusiveOr`. `is("LeftOnly")` is a type guard that
|
|
210
|
+
* narrows an `InclusiveOr` to its `LeftOnly` member, and likewise for `"RightOnly"` and
|
|
211
|
+
* `"LeftAndRight"`.
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* ```ts
|
|
215
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
216
|
+
*
|
|
217
|
+
* assert.deepStrictEqual(InclusiveOr.is("LeftOnly")(InclusiveOr.LeftOnly({ left: 1 })), true)
|
|
218
|
+
* assert.deepStrictEqual(
|
|
219
|
+
* InclusiveOr.is("LeftOnly")(InclusiveOr.RightOnly({ right: "a" })),
|
|
220
|
+
* false
|
|
221
|
+
* )
|
|
222
|
+
* ```
|
|
223
|
+
*
|
|
224
|
+
* @category guards
|
|
225
|
+
* @since 0.0.0
|
|
226
|
+
*/
|
|
227
|
+
export declare const is: <Tag extends "LeftOnly" | "RightOnly" | "LeftAndRight">(tag: Tag) => {
|
|
228
|
+
<T extends {
|
|
229
|
+
readonly _tag: "LeftOnly";
|
|
230
|
+
readonly left: any;
|
|
231
|
+
} | {
|
|
232
|
+
readonly _tag: "RightOnly";
|
|
233
|
+
readonly right: any;
|
|
234
|
+
} | {
|
|
235
|
+
readonly _tag: "LeftAndRight";
|
|
236
|
+
readonly left: any;
|
|
237
|
+
readonly right: any;
|
|
238
|
+
}>(u: T): u is T & {
|
|
239
|
+
readonly _tag: Tag;
|
|
240
|
+
};
|
|
241
|
+
(u: unknown): u is Extract<{
|
|
242
|
+
readonly _tag: "LeftOnly";
|
|
243
|
+
readonly left: unknown;
|
|
244
|
+
}, {
|
|
245
|
+
readonly _tag: Tag;
|
|
246
|
+
}> | Extract<{
|
|
247
|
+
readonly _tag: "RightOnly";
|
|
248
|
+
readonly right: unknown;
|
|
249
|
+
}, {
|
|
250
|
+
readonly _tag: Tag;
|
|
251
|
+
}> | Extract<{
|
|
252
|
+
readonly _tag: "LeftAndRight";
|
|
253
|
+
readonly left: unknown;
|
|
254
|
+
readonly right: unknown;
|
|
255
|
+
}, {
|
|
256
|
+
readonly _tag: Tag;
|
|
257
|
+
}>;
|
|
258
|
+
};
|
|
259
|
+
/**
|
|
260
|
+
* Folds an `InclusiveOr` over its three tags. Provide a handler for `LeftOnly`,
|
|
261
|
+
* `RightOnly`, and `LeftAndRight` and `match` returns a function from an `InclusiveOr`
|
|
262
|
+
* to the handlers' common result type.
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* ```ts
|
|
266
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
267
|
+
*
|
|
268
|
+
* const describe = InclusiveOr.match({
|
|
269
|
+
* LeftOnly: ({ left }) => `left ${left}`,
|
|
270
|
+
* RightOnly: ({ right }) => `right ${right}`,
|
|
271
|
+
* LeftAndRight: ({ left, right }) => `both ${left}/${right}`
|
|
272
|
+
* })
|
|
273
|
+
*
|
|
274
|
+
* assert.deepStrictEqual(
|
|
275
|
+
* describe(InclusiveOr.LeftAndRight({ left: 1, right: "a" })),
|
|
276
|
+
* "both 1/a"
|
|
277
|
+
* )
|
|
278
|
+
* ```
|
|
279
|
+
*
|
|
280
|
+
* @category pattern matching
|
|
281
|
+
* @since 0.0.0
|
|
282
|
+
*/
|
|
283
|
+
export declare const match: {
|
|
284
|
+
<A, B, C, D, Cases extends {
|
|
285
|
+
readonly LeftOnly: (args: {
|
|
286
|
+
readonly _tag: "LeftOnly";
|
|
287
|
+
readonly left: A;
|
|
288
|
+
}) => any;
|
|
289
|
+
readonly RightOnly: (args: {
|
|
290
|
+
readonly _tag: "RightOnly";
|
|
291
|
+
readonly right: B;
|
|
292
|
+
}) => any;
|
|
293
|
+
readonly LeftAndRight: (args: {
|
|
294
|
+
readonly _tag: "LeftAndRight";
|
|
295
|
+
readonly left: A;
|
|
296
|
+
readonly right: B;
|
|
297
|
+
}) => any;
|
|
298
|
+
}>(cases: Cases): (self: {
|
|
299
|
+
readonly _tag: "LeftOnly";
|
|
300
|
+
readonly left: A;
|
|
301
|
+
} | {
|
|
302
|
+
readonly _tag: "RightOnly";
|
|
303
|
+
readonly right: B;
|
|
304
|
+
} | {
|
|
305
|
+
readonly _tag: "LeftAndRight";
|
|
306
|
+
readonly left: A;
|
|
307
|
+
readonly right: B;
|
|
308
|
+
}) => import("effect/Unify").Unify<ReturnType<Cases["LeftOnly" | "RightOnly" | "LeftAndRight"]>>;
|
|
309
|
+
<A, B, C, D, Cases extends {
|
|
310
|
+
readonly LeftOnly: (args: {
|
|
311
|
+
readonly _tag: "LeftOnly";
|
|
312
|
+
readonly left: A;
|
|
313
|
+
}) => any;
|
|
314
|
+
readonly RightOnly: (args: {
|
|
315
|
+
readonly _tag: "RightOnly";
|
|
316
|
+
readonly right: B;
|
|
317
|
+
}) => any;
|
|
318
|
+
readonly LeftAndRight: (args: {
|
|
319
|
+
readonly _tag: "LeftAndRight";
|
|
320
|
+
readonly left: A;
|
|
321
|
+
readonly right: B;
|
|
322
|
+
}) => any;
|
|
323
|
+
}>(self: {
|
|
324
|
+
readonly _tag: "LeftOnly";
|
|
325
|
+
readonly left: A;
|
|
326
|
+
} | {
|
|
327
|
+
readonly _tag: "RightOnly";
|
|
328
|
+
readonly right: B;
|
|
329
|
+
} | {
|
|
330
|
+
readonly _tag: "LeftAndRight";
|
|
331
|
+
readonly left: A;
|
|
332
|
+
readonly right: B;
|
|
333
|
+
}, cases: Cases): import("effect/Unify").Unify<ReturnType<Cases["LeftOnly" | "RightOnly" | "LeftAndRight"]>>;
|
|
334
|
+
};
|
|
335
|
+
/**
|
|
336
|
+
* Builds an `InclusiveOr` known to carry a `left`, choosing `LeftAndRight` when `right`
|
|
337
|
+
* is present and `LeftOnly` otherwise.
|
|
338
|
+
*
|
|
339
|
+
* Use it when the `left` is mandatory and the `right` is an optional companion:
|
|
340
|
+
* pass an absent (`null`/`undefined`) `right` to get a `LeftOnly`, or a present
|
|
341
|
+
* one to get a `LeftAndRight`. The return type `WithLeft<L, R>` reflects that a
|
|
342
|
+
* `left` is always present.
|
|
343
|
+
*
|
|
344
|
+
* @example
|
|
345
|
+
* ```ts
|
|
346
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
347
|
+
*
|
|
348
|
+
* assert.deepStrictEqual(
|
|
349
|
+
* InclusiveOr.WithLeft({ left: 1, right: "a" }),
|
|
350
|
+
* InclusiveOr.LeftAndRight({ left: 1, right: "a" })
|
|
351
|
+
* )
|
|
352
|
+
*
|
|
353
|
+
* assert.deepStrictEqual(
|
|
354
|
+
* InclusiveOr.WithLeft({ left: 1 }),
|
|
355
|
+
* InclusiveOr.LeftOnly({ left: 1 })
|
|
356
|
+
* )
|
|
357
|
+
* ```
|
|
358
|
+
*
|
|
359
|
+
* @category constructors
|
|
360
|
+
* @since 0.0.0
|
|
361
|
+
*/
|
|
362
|
+
export declare const WithLeft: <L, R>({ left, right, }: {
|
|
363
|
+
left: L;
|
|
364
|
+
right?: R | undefined;
|
|
365
|
+
}) => WithLeft<L, R>;
|
|
366
|
+
/**
|
|
367
|
+
* Builds an `InclusiveOr` known to carry a `right`, choosing `LeftAndRight` when `left`
|
|
368
|
+
* is present and `RightOnly` otherwise.
|
|
369
|
+
*
|
|
370
|
+
* The mirror of `WithLeft`: the `right` is mandatory and the `left` is an
|
|
371
|
+
* optional companion. Pass an absent (`null`/`undefined`) `left` to get a
|
|
372
|
+
* `RightOnly`, or a present one to get a `LeftAndRight`. The return type
|
|
373
|
+
* `WithRight<L, R>` reflects that a `right` is always present.
|
|
374
|
+
*
|
|
375
|
+
* @example
|
|
376
|
+
* ```ts
|
|
377
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
378
|
+
*
|
|
379
|
+
* assert.deepStrictEqual(
|
|
380
|
+
* InclusiveOr.WithRight({ left: 1, right: "a" }),
|
|
381
|
+
* InclusiveOr.LeftAndRight({ left: 1, right: "a" })
|
|
382
|
+
* )
|
|
383
|
+
*
|
|
384
|
+
* assert.deepStrictEqual(
|
|
385
|
+
* InclusiveOr.WithRight({ right: "a" }),
|
|
386
|
+
* InclusiveOr.RightOnly({ right: "a" })
|
|
387
|
+
* )
|
|
388
|
+
* ```
|
|
389
|
+
*
|
|
390
|
+
* @category constructors
|
|
391
|
+
* @since 0.0.0
|
|
392
|
+
*/
|
|
393
|
+
export declare const WithRight: <L, R>({ left, right, }: {
|
|
394
|
+
left?: L | undefined;
|
|
395
|
+
right: R;
|
|
396
|
+
}) => WithRight<L, R>;
|
|
397
|
+
/**
|
|
398
|
+
* Builds an `InclusiveOr` from a pair of possibly-nullish inputs, wrapping the result in
|
|
399
|
+
* an `Option` so the all-absent case is expressible.
|
|
400
|
+
*
|
|
401
|
+
* Returns `Option.some(LeftAndRight)` when both are present, `Option.some(LeftOnly)`
|
|
402
|
+
* or `Option.some(RightOnly)` when exactly one is present, and `Option.none()`
|
|
403
|
+
* when both are nullish. Use it as the total entry point for turning two optional
|
|
404
|
+
* values into an `InclusiveOr`.
|
|
405
|
+
*
|
|
406
|
+
* @example
|
|
407
|
+
* ```ts
|
|
408
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
409
|
+
* import { Option } from "effect"
|
|
410
|
+
*
|
|
411
|
+
* assert.deepStrictEqual(
|
|
412
|
+
* InclusiveOr.optionFromNullables({ left: 1, right: "a" }),
|
|
413
|
+
* Option.some(InclusiveOr.LeftAndRight({ left: 1, right: "a" }))
|
|
414
|
+
* )
|
|
415
|
+
*
|
|
416
|
+
* assert.deepStrictEqual(
|
|
417
|
+
* InclusiveOr.optionFromNullables({ left: 1, right: null }),
|
|
418
|
+
* Option.some(InclusiveOr.LeftOnly({ left: 1 }))
|
|
419
|
+
* )
|
|
420
|
+
*
|
|
421
|
+
* assert.deepStrictEqual(
|
|
422
|
+
* InclusiveOr.optionFromNullables({ left: null, right: undefined }),
|
|
423
|
+
* Option.none()
|
|
424
|
+
* )
|
|
425
|
+
* ```
|
|
426
|
+
*
|
|
427
|
+
* @category constructors
|
|
428
|
+
* @since 0.0.0
|
|
429
|
+
*/
|
|
430
|
+
export declare const optionFromNullables: <L, R>({ left, right, }: {
|
|
431
|
+
left?: L | null | undefined;
|
|
432
|
+
right?: R | null | undefined;
|
|
433
|
+
}) => Option.Option<InclusiveOr<L, R>>;
|
|
434
|
+
/**
|
|
435
|
+
* Builds an `InclusiveOr` from a pair of possibly-nullish inputs, falling back to the
|
|
436
|
+
* `orElse` thunk when both are absent.
|
|
437
|
+
*
|
|
438
|
+
* The non-optional companion to `optionFromNullables`: it unwraps the same logic
|
|
439
|
+
* but resolves the all-absent case with `orElse` instead of an `Option`. The
|
|
440
|
+
* default `orElse` throws, so omit it only when at least one side is guaranteed
|
|
441
|
+
* present.
|
|
442
|
+
*
|
|
443
|
+
* @example
|
|
444
|
+
* ```ts
|
|
445
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
446
|
+
*
|
|
447
|
+
* assert.deepStrictEqual(
|
|
448
|
+
* InclusiveOr.fromNullables({ left: 1, right: "a" }),
|
|
449
|
+
* InclusiveOr.LeftAndRight({ left: 1, right: "a" })
|
|
450
|
+
* )
|
|
451
|
+
*
|
|
452
|
+
* // Both absent — fall back via orElse instead of throwing
|
|
453
|
+
* assert.deepStrictEqual(
|
|
454
|
+
* InclusiveOr.fromNullables({
|
|
455
|
+
* left: null,
|
|
456
|
+
* right: null,
|
|
457
|
+
* orElse: () => InclusiveOr.LeftOnly({ left: 0 })
|
|
458
|
+
* }),
|
|
459
|
+
* InclusiveOr.LeftOnly({ left: 0 })
|
|
460
|
+
* )
|
|
461
|
+
* ```
|
|
462
|
+
*
|
|
463
|
+
* @category constructors
|
|
464
|
+
* @since 0.0.0
|
|
465
|
+
*/
|
|
466
|
+
export declare const fromNullables: <L, R>({ left, right, orElse, }: {
|
|
467
|
+
left?: L | null | undefined;
|
|
468
|
+
right?: R | null | undefined;
|
|
469
|
+
orElse?: () => InclusiveOr<L, R>;
|
|
470
|
+
}) => InclusiveOr<L, R>;
|
|
471
|
+
/**
|
|
472
|
+
* Folds an `InclusiveOr` from the left's perspective, collapsing the three tags into two
|
|
473
|
+
* handlers.
|
|
474
|
+
*
|
|
475
|
+
* Both `LeftOnly` and `LeftAndRight` carry a `left`, so they route to the `Left`
|
|
476
|
+
* handler; only `RightOnly` lacks a `left` and routes to `RightOnly`. Use it when
|
|
477
|
+
* you care about the `left` value and treat the right-only case as the exception.
|
|
478
|
+
*
|
|
479
|
+
* @example
|
|
480
|
+
* ```ts
|
|
481
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
482
|
+
*
|
|
483
|
+
* const onLeft = InclusiveOr.matchLeft({
|
|
484
|
+
* Left: (left: number) => `left ${left}`,
|
|
485
|
+
* RightOnly: (right: string) => `right ${right}`
|
|
486
|
+
* })
|
|
487
|
+
*
|
|
488
|
+
* assert.deepStrictEqual(onLeft(InclusiveOr.LeftOnly({ left: 1 })), "left 1")
|
|
489
|
+
* assert.deepStrictEqual(
|
|
490
|
+
* onLeft(InclusiveOr.LeftAndRight({ left: 1, right: "a" })),
|
|
491
|
+
* "left 1"
|
|
492
|
+
* )
|
|
493
|
+
* assert.deepStrictEqual(onLeft(InclusiveOr.RightOnly({ right: "a" })), "right a")
|
|
494
|
+
* ```
|
|
495
|
+
*
|
|
496
|
+
* @category pattern matching
|
|
497
|
+
* @since 0.0.0
|
|
498
|
+
*/
|
|
499
|
+
export declare const matchLeft: <L, R, A>({ Left, RightOnly, }: {
|
|
500
|
+
Left: (left: L) => A;
|
|
501
|
+
RightOnly: (right: R) => A;
|
|
502
|
+
}) => (inclusiveOr: InclusiveOr<L, R>) => A;
|
|
503
|
+
/**
|
|
504
|
+
* Folds an `InclusiveOr` from the right's perspective, collapsing the three tags into two
|
|
505
|
+
* handlers.
|
|
506
|
+
*
|
|
507
|
+
* The mirror of `matchLeft`: both `RightOnly` and `LeftAndRight` carry a `right`,
|
|
508
|
+
* so they route to the `Right` handler; only `LeftOnly` lacks a `right` and routes
|
|
509
|
+
* to `LeftOnly`. Use it when you care about the `right` value and treat the
|
|
510
|
+
* left-only case as the exception.
|
|
511
|
+
*
|
|
512
|
+
* @example
|
|
513
|
+
* ```ts
|
|
514
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
515
|
+
*
|
|
516
|
+
* const onRight = InclusiveOr.matchRight({
|
|
517
|
+
* LeftOnly: (left: number) => `left ${left}`,
|
|
518
|
+
* Right: (right: string) => `right ${right}`
|
|
519
|
+
* })
|
|
520
|
+
*
|
|
521
|
+
* assert.deepStrictEqual(onRight(InclusiveOr.RightOnly({ right: "a" })), "right a")
|
|
522
|
+
* assert.deepStrictEqual(
|
|
523
|
+
* onRight(InclusiveOr.LeftAndRight({ left: 1, right: "a" })),
|
|
524
|
+
* "right a"
|
|
525
|
+
* )
|
|
526
|
+
* assert.deepStrictEqual(onRight(InclusiveOr.LeftOnly({ left: 1 })), "left 1")
|
|
527
|
+
* ```
|
|
528
|
+
*
|
|
529
|
+
* @category pattern matching
|
|
530
|
+
* @since 0.0.0
|
|
531
|
+
*/
|
|
532
|
+
export declare const matchRight: <L, R, A>({ LeftOnly, Right, }: {
|
|
533
|
+
LeftOnly: (left: L) => A;
|
|
534
|
+
Right: (right: R) => A;
|
|
535
|
+
}) => (inclusiveOr: InclusiveOr<L, R>) => A;
|
|
536
|
+
/**
|
|
537
|
+
* Completes an `InclusiveOr` into a guaranteed `LeftAndRight` by filling whichever side
|
|
538
|
+
* is missing from the matching `orElse` thunk.
|
|
539
|
+
*
|
|
540
|
+
* A `LeftAndRight` passes through unchanged; a `LeftOnly` gains a `right` from
|
|
541
|
+
* `orElseRight`; a `RightOnly` gains a `left` from `orElseLeft`. Use it to
|
|
542
|
+
* normalise a partial `InclusiveOr` into the both-present shape before reading both
|
|
543
|
+
* sides.
|
|
544
|
+
*
|
|
545
|
+
* @example
|
|
546
|
+
* ```ts
|
|
547
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
548
|
+
*
|
|
549
|
+
* const fill = InclusiveOr.orElse({
|
|
550
|
+
* orElseLeft: () => 0,
|
|
551
|
+
* orElseRight: () => "default"
|
|
552
|
+
* })
|
|
553
|
+
*
|
|
554
|
+
* assert.deepStrictEqual(
|
|
555
|
+
* fill(InclusiveOr.LeftOnly({ left: 1 })),
|
|
556
|
+
* InclusiveOr.LeftAndRight({ left: 1, right: "default" })
|
|
557
|
+
* )
|
|
558
|
+
* assert.deepStrictEqual(
|
|
559
|
+
* fill(InclusiveOr.RightOnly({ right: "a" })),
|
|
560
|
+
* InclusiveOr.LeftAndRight({ left: 0, right: "a" })
|
|
561
|
+
* )
|
|
562
|
+
* ```
|
|
563
|
+
*
|
|
564
|
+
* @category getters
|
|
565
|
+
* @since 0.0.0
|
|
566
|
+
*/
|
|
567
|
+
export declare const orElse: <L2, R2>({ orElseLeft, orElseRight, }: {
|
|
568
|
+
orElseLeft: () => L2;
|
|
569
|
+
orElseRight: () => R2;
|
|
570
|
+
}) => (<L, R>(inclusiveOr: InclusiveOr<L, R>) => LeftAndRight<L | L2, R | R2>);
|
|
571
|
+
/**
|
|
572
|
+
* Completes an `InclusiveOr` into a `LeftAndRight` whose missing side is filled with
|
|
573
|
+
* `undefined`.
|
|
574
|
+
*
|
|
575
|
+
* A specialisation of `orElse` that supplies `undefined` for whichever side is
|
|
576
|
+
* absent, so the result always exposes both `left` and `right` keys (each
|
|
577
|
+
* possibly `undefined`). Use it when you want to destructure both sides without
|
|
578
|
+
* branching on the tag.
|
|
579
|
+
*
|
|
580
|
+
* @example
|
|
581
|
+
* ```ts
|
|
582
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
583
|
+
*
|
|
584
|
+
* assert.deepStrictEqual(
|
|
585
|
+
* InclusiveOr.orUndefined(InclusiveOr.LeftOnly({ left: 1 })),
|
|
586
|
+
* InclusiveOr.LeftAndRight({ left: 1, right: undefined })
|
|
587
|
+
* )
|
|
588
|
+
* assert.deepStrictEqual(
|
|
589
|
+
* InclusiveOr.orUndefined(InclusiveOr.RightOnly({ right: "a" })),
|
|
590
|
+
* InclusiveOr.LeftAndRight({ left: undefined, right: "a" })
|
|
591
|
+
* )
|
|
592
|
+
* ```
|
|
593
|
+
*
|
|
594
|
+
* @category getters
|
|
595
|
+
* @since 0.0.0
|
|
596
|
+
*/
|
|
597
|
+
export declare const orUndefined: <L, R>(inclusiveOr: {
|
|
598
|
+
readonly _tag: "LeftOnly";
|
|
599
|
+
readonly left: L;
|
|
600
|
+
} | {
|
|
601
|
+
readonly _tag: "RightOnly";
|
|
602
|
+
readonly right: R;
|
|
603
|
+
} | {
|
|
604
|
+
readonly _tag: "LeftAndRight";
|
|
605
|
+
readonly left: L;
|
|
606
|
+
readonly right: R;
|
|
607
|
+
}) => {
|
|
608
|
+
readonly _tag: "LeftAndRight";
|
|
609
|
+
readonly left: L | undefined;
|
|
610
|
+
readonly right: R | undefined;
|
|
611
|
+
} & {
|
|
612
|
+
_tag: "LeftAndRight";
|
|
613
|
+
};
|
|
614
|
+
/**
|
|
615
|
+
* Extracts the `left` of an `InclusiveOr`, falling back to `orElseReturn` when no `left`
|
|
616
|
+
* is present.
|
|
617
|
+
*
|
|
618
|
+
* `LeftOnly` and `LeftAndRight` return their `left`; `RightOnly` returns the
|
|
619
|
+
* result of `orElseReturn`. Use it to read the left side with a default in one
|
|
620
|
+
* step.
|
|
621
|
+
*
|
|
622
|
+
* @example
|
|
623
|
+
* ```ts
|
|
624
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
625
|
+
*
|
|
626
|
+
* const leftOrZero = InclusiveOr.leftOrElse(() => 0)
|
|
627
|
+
*
|
|
628
|
+
* assert.deepStrictEqual(leftOrZero(InclusiveOr.LeftOnly({ left: 1 })), 1)
|
|
629
|
+
* assert.deepStrictEqual(
|
|
630
|
+
* leftOrZero(InclusiveOr.LeftAndRight({ left: 1, right: "a" })),
|
|
631
|
+
* 1
|
|
632
|
+
* )
|
|
633
|
+
* assert.deepStrictEqual(leftOrZero(InclusiveOr.RightOnly({ right: "a" })), 0)
|
|
634
|
+
* ```
|
|
635
|
+
*
|
|
636
|
+
* @category getters
|
|
637
|
+
* @since 0.0.0
|
|
638
|
+
*/
|
|
639
|
+
export declare const leftOrElse: <A>(orElseReturn: () => A) => <L, R>(inclusiveOr: InclusiveOr<L, R>) => L | A;
|
|
640
|
+
/**
|
|
641
|
+
* Extracts the `left` of an `InclusiveOr`, returning `undefined` when no `left` is
|
|
642
|
+
* present.
|
|
643
|
+
*
|
|
644
|
+
* A specialisation of `leftOrElse` whose fallback is `undefined`: `LeftOnly` and
|
|
645
|
+
* `LeftAndRight` yield their `left`, while `RightOnly` yields `undefined`.
|
|
646
|
+
*
|
|
647
|
+
* @example
|
|
648
|
+
* ```ts
|
|
649
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
650
|
+
*
|
|
651
|
+
* assert.deepStrictEqual(InclusiveOr.leftOrUndefined(InclusiveOr.LeftOnly({ left: 1 })), 1)
|
|
652
|
+
* assert.deepStrictEqual(
|
|
653
|
+
* InclusiveOr.leftOrUndefined(InclusiveOr.RightOnly({ right: "a" })),
|
|
654
|
+
* undefined
|
|
655
|
+
* )
|
|
656
|
+
* ```
|
|
657
|
+
*
|
|
658
|
+
* @category getters
|
|
659
|
+
* @since 0.0.0
|
|
660
|
+
*/
|
|
661
|
+
export declare const leftOrUndefined: <L, R>(inclusiveOr: {
|
|
662
|
+
readonly _tag: "LeftOnly";
|
|
663
|
+
readonly left: L;
|
|
664
|
+
} | {
|
|
665
|
+
readonly _tag: "RightOnly";
|
|
666
|
+
readonly right: R;
|
|
667
|
+
} | {
|
|
668
|
+
readonly _tag: "LeftAndRight";
|
|
669
|
+
readonly left: L;
|
|
670
|
+
readonly right: R;
|
|
671
|
+
}) => L | undefined;
|
|
672
|
+
/**
|
|
673
|
+
* Extracts the `right` of an `InclusiveOr`, falling back to `orElseReturn` when no
|
|
674
|
+
* `right` is present.
|
|
675
|
+
*
|
|
676
|
+
* The mirror of `leftOrElse`: `RightOnly` and `LeftAndRight` return their
|
|
677
|
+
* `right`; `LeftOnly` returns the result of `orElseReturn`.
|
|
678
|
+
*
|
|
679
|
+
* @example
|
|
680
|
+
* ```ts
|
|
681
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
682
|
+
*
|
|
683
|
+
* const rightOrDefault = InclusiveOr.rightOrElse(() => "default")
|
|
684
|
+
*
|
|
685
|
+
* assert.deepStrictEqual(
|
|
686
|
+
* rightOrDefault(InclusiveOr.RightOnly({ right: "a" })),
|
|
687
|
+
* "a"
|
|
688
|
+
* )
|
|
689
|
+
* assert.deepStrictEqual(
|
|
690
|
+
* rightOrDefault(InclusiveOr.LeftOnly({ left: 1 })),
|
|
691
|
+
* "default"
|
|
692
|
+
* )
|
|
693
|
+
* ```
|
|
694
|
+
*
|
|
695
|
+
* @category getters
|
|
696
|
+
* @since 0.0.0
|
|
697
|
+
*/
|
|
698
|
+
export declare const rightOrElse: <A>(orElseReturn: () => A) => <L, R>(inclusiveOr: InclusiveOr<L, R>) => R | A;
|
|
699
|
+
/**
|
|
700
|
+
* Extracts the `right` of an `InclusiveOr`, returning `undefined` when no `right` is
|
|
701
|
+
* present.
|
|
702
|
+
*
|
|
703
|
+
* A specialisation of `rightOrElse` whose fallback is `undefined`: `RightOnly` and
|
|
704
|
+
* `LeftAndRight` yield their `right`, while `LeftOnly` yields `undefined`.
|
|
705
|
+
*
|
|
706
|
+
* @example
|
|
707
|
+
* ```ts
|
|
708
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
709
|
+
*
|
|
710
|
+
* assert.deepStrictEqual(
|
|
711
|
+
* InclusiveOr.rightOrUndefined(InclusiveOr.RightOnly({ right: "a" })),
|
|
712
|
+
* "a"
|
|
713
|
+
* )
|
|
714
|
+
* assert.deepStrictEqual(
|
|
715
|
+
* InclusiveOr.rightOrUndefined(InclusiveOr.LeftOnly({ left: 1 })),
|
|
716
|
+
* undefined
|
|
717
|
+
* )
|
|
718
|
+
* ```
|
|
719
|
+
*
|
|
720
|
+
* @category getters
|
|
721
|
+
* @since 0.0.0
|
|
722
|
+
*/
|
|
723
|
+
export declare const rightOrUndefined: <L, R>(inclusiveOr: {
|
|
724
|
+
readonly _tag: "LeftOnly";
|
|
725
|
+
readonly left: L;
|
|
726
|
+
} | {
|
|
727
|
+
readonly _tag: "RightOnly";
|
|
728
|
+
readonly right: R;
|
|
729
|
+
} | {
|
|
730
|
+
readonly _tag: "LeftAndRight";
|
|
731
|
+
readonly left: L;
|
|
732
|
+
readonly right: R;
|
|
733
|
+
}) => R | undefined;
|
|
734
|
+
/**
|
|
735
|
+
* Extracts the `right` of an `InclusiveOr` as an `Option`.
|
|
736
|
+
*
|
|
737
|
+
* `RightOnly` and `LeftAndRight` yield `Option.some(right)`; `LeftOnly` yields
|
|
738
|
+
* `Option.none()`. Use it when you want to chain the right side through `Option`
|
|
739
|
+
* combinators rather than fall back to a default eagerly.
|
|
740
|
+
*
|
|
741
|
+
* @example
|
|
742
|
+
* ```ts
|
|
743
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
744
|
+
* import { Option } from "effect"
|
|
745
|
+
*
|
|
746
|
+
* assert.deepStrictEqual(
|
|
747
|
+
* InclusiveOr.rightOption(InclusiveOr.RightOnly({ right: "a" })),
|
|
748
|
+
* Option.some("a")
|
|
749
|
+
* )
|
|
750
|
+
* assert.deepStrictEqual(
|
|
751
|
+
* InclusiveOr.rightOption(InclusiveOr.LeftOnly({ left: 1 })),
|
|
752
|
+
* Option.none()
|
|
753
|
+
* )
|
|
754
|
+
* ```
|
|
755
|
+
*
|
|
756
|
+
* @category getters
|
|
757
|
+
* @since 0.0.0
|
|
758
|
+
*/
|
|
759
|
+
export declare const rightOption: <L, R>(inclusiveOr: InclusiveOr<L, R>) => Option.Option<R>;
|
|
760
|
+
/**
|
|
761
|
+
* Extracts the `left` of an `InclusiveOr` as an `Option`.
|
|
762
|
+
*
|
|
763
|
+
* The mirror of `rightOption`: `LeftOnly` and `LeftAndRight` yield
|
|
764
|
+
* `Option.some(left)`, while `RightOnly` yields `Option.none()`.
|
|
765
|
+
*
|
|
766
|
+
* @example
|
|
767
|
+
* ```ts
|
|
768
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
769
|
+
* import { Option } from "effect"
|
|
770
|
+
*
|
|
771
|
+
* assert.deepStrictEqual(
|
|
772
|
+
* InclusiveOr.leftOption(InclusiveOr.LeftOnly({ left: 1 })),
|
|
773
|
+
* Option.some(1)
|
|
774
|
+
* )
|
|
775
|
+
* assert.deepStrictEqual(
|
|
776
|
+
* InclusiveOr.leftOption(InclusiveOr.RightOnly({ right: "a" })),
|
|
777
|
+
* Option.none()
|
|
778
|
+
* )
|
|
779
|
+
* ```
|
|
780
|
+
*
|
|
781
|
+
* @category getters
|
|
782
|
+
* @since 0.0.0
|
|
783
|
+
*/
|
|
784
|
+
export declare const leftOption: <L, R>(inclusiveOr: InclusiveOr<L, R>) => Option.Option<L>;
|
|
785
|
+
/**
|
|
786
|
+
* Transforms both sides of an `InclusiveOr`, applying `mapLeft` to any `left` and
|
|
787
|
+
* `mapRight` to any `right`.
|
|
788
|
+
*
|
|
789
|
+
* Each constructor is rebuilt with its mapped contents, so `LeftOnly` maps only
|
|
790
|
+
* the left, `RightOnly` only the right, and `LeftAndRight` both. The tag is
|
|
791
|
+
* preserved. Use it as the bifunctor map over `InclusiveOr`.
|
|
792
|
+
*
|
|
793
|
+
* @example
|
|
794
|
+
* ```ts
|
|
795
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
796
|
+
*
|
|
797
|
+
* const both = InclusiveOr.mapBoth({
|
|
798
|
+
* mapLeft: (left: number) => left + 1,
|
|
799
|
+
* mapRight: (right: string) => right.toUpperCase()
|
|
800
|
+
* })
|
|
801
|
+
*
|
|
802
|
+
* assert.deepStrictEqual(
|
|
803
|
+
* both(InclusiveOr.LeftAndRight({ left: 1, right: "a" })),
|
|
804
|
+
* InclusiveOr.LeftAndRight({ left: 2, right: "A" })
|
|
805
|
+
* )
|
|
806
|
+
* assert.deepStrictEqual(
|
|
807
|
+
* both(InclusiveOr.LeftOnly({ left: 1 })),
|
|
808
|
+
* InclusiveOr.LeftOnly({ left: 2 })
|
|
809
|
+
* )
|
|
810
|
+
* ```
|
|
811
|
+
*
|
|
812
|
+
* @category mapping
|
|
813
|
+
* @since 0.0.0
|
|
814
|
+
*/
|
|
815
|
+
export declare const mapBoth: <L1, R1, L2, R2>({ mapLeft, mapRight, }: {
|
|
816
|
+
mapLeft: (left: L1) => L2;
|
|
817
|
+
mapRight: (right: R1) => R2;
|
|
818
|
+
}) => ((inclusiveOr: InclusiveOr<L1, R1>) => InclusiveOr<L2, R2>);
|
|
819
|
+
/**
|
|
820
|
+
* Effectful `mapBoth`: transforms each present side through an `Effect`,
|
|
821
|
+
* reassembling the results into an `InclusiveOr` inside an `Effect`.
|
|
822
|
+
*
|
|
823
|
+
* For `LeftAndRight` both effects run via `Effect.all` and their results are
|
|
824
|
+
* combined; `LeftOnly`/`RightOnly` run only the relevant effect. Errors and
|
|
825
|
+
* requirements from both mappers are unioned into the result type. Use it when
|
|
826
|
+
* mapping an `InclusiveOr`'s sides requires effects (validation, IO).
|
|
827
|
+
*
|
|
828
|
+
* @example
|
|
829
|
+
* ```ts
|
|
830
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
831
|
+
* import { Effect } from "effect"
|
|
832
|
+
*
|
|
833
|
+
* const both = InclusiveOr.mapBothEffect({
|
|
834
|
+
* mapLeft: (left: number) => Effect.succeed(left + 1),
|
|
835
|
+
* mapRight: (right: string) => Effect.succeed(right.toUpperCase())
|
|
836
|
+
* })
|
|
837
|
+
*
|
|
838
|
+
* assert.deepStrictEqual(
|
|
839
|
+
* Effect.runSync(both(InclusiveOr.LeftAndRight({ left: 1, right: "a" }))),
|
|
840
|
+
* InclusiveOr.LeftAndRight({ left: 2, right: "A" })
|
|
841
|
+
* )
|
|
842
|
+
* ```
|
|
843
|
+
*
|
|
844
|
+
* @category sequencing
|
|
845
|
+
* @since 0.0.0
|
|
846
|
+
*/
|
|
847
|
+
export declare const mapBothEffect: <L1, R1, L2, R2, EL, ER, RL, RR>({ mapLeft, mapRight, }: {
|
|
848
|
+
mapLeft: (left: L1) => Effect.Effect<L2, EL, RL>;
|
|
849
|
+
mapRight: (right: R1) => Effect.Effect<R2, ER, RR>;
|
|
850
|
+
}) => ((inclusiveOr: InclusiveOr<L1, R1>) => Effect.Effect<InclusiveOr<L2, R2>, EL | ER, RL | RR>);
|
|
851
|
+
/**
|
|
852
|
+
* Transforms the `left` of an `InclusiveOr`, leaving any `right` untouched.
|
|
853
|
+
*
|
|
854
|
+
* A specialisation of `mapBoth` with the right mapper set to `identity`:
|
|
855
|
+
* `LeftOnly` and `LeftAndRight` have their `left` mapped, while `RightOnly` passes
|
|
856
|
+
* through unchanged.
|
|
857
|
+
*
|
|
858
|
+
* @example
|
|
859
|
+
* ```ts
|
|
860
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
861
|
+
*
|
|
862
|
+
* const inc = InclusiveOr.mapLeft((left: number) => left + 1)
|
|
863
|
+
*
|
|
864
|
+
* assert.deepStrictEqual(
|
|
865
|
+
* inc(InclusiveOr.LeftAndRight({ left: 1, right: "a" })),
|
|
866
|
+
* InclusiveOr.LeftAndRight({ left: 2, right: "a" })
|
|
867
|
+
* )
|
|
868
|
+
* assert.deepStrictEqual(
|
|
869
|
+
* inc(InclusiveOr.RightOnly({ right: "a" })),
|
|
870
|
+
* InclusiveOr.RightOnly({ right: "a" })
|
|
871
|
+
* )
|
|
872
|
+
* ```
|
|
873
|
+
*
|
|
874
|
+
* @category mapping
|
|
875
|
+
* @since 0.0.0
|
|
876
|
+
*/
|
|
877
|
+
export declare const mapLeft: <L1, L2>(mapLeft: (left: L1) => L2) => (<R>(inclusiveOr: InclusiveOr<L1, R>) => InclusiveOr<L2, R>);
|
|
878
|
+
/**
|
|
879
|
+
* Chains the `left` of an `InclusiveOr` into a new `InclusiveOr`, flattening the result.
|
|
880
|
+
*
|
|
881
|
+
* Whenever a `left` is present (`LeftOnly` or `LeftAndRight`) it is passed to
|
|
882
|
+
* `mapLeft`, whose returned `InclusiveOr` replaces the original; `RightOnly` passes
|
|
883
|
+
* through unchanged. Use it to sequence left-driven computations that themselves
|
|
884
|
+
* produce an `InclusiveOr`.
|
|
885
|
+
*
|
|
886
|
+
* @example
|
|
887
|
+
* ```ts
|
|
888
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
889
|
+
*
|
|
890
|
+
* const chain = InclusiveOr.flatMapLeft((left: number) =>
|
|
891
|
+
* left > 0
|
|
892
|
+
* ? InclusiveOr.LeftOnly({ left: left * 10 })
|
|
893
|
+
* : InclusiveOr.RightOnly({ right: "non-positive" })
|
|
894
|
+
* )
|
|
895
|
+
*
|
|
896
|
+
* assert.deepStrictEqual(
|
|
897
|
+
* chain(InclusiveOr.LeftOnly({ left: 2 })),
|
|
898
|
+
* InclusiveOr.LeftOnly({ left: 20 })
|
|
899
|
+
* )
|
|
900
|
+
* assert.deepStrictEqual(
|
|
901
|
+
* chain(InclusiveOr.RightOnly({ right: "a" })),
|
|
902
|
+
* InclusiveOr.RightOnly({ right: "a" })
|
|
903
|
+
* )
|
|
904
|
+
* ```
|
|
905
|
+
*
|
|
906
|
+
* @category sequencing
|
|
907
|
+
* @since 0.0.0
|
|
908
|
+
*/
|
|
909
|
+
export declare const flatMapLeft: <L1, L2, R2>(mapLeft: (left: L1) => InclusiveOr<L2, R2>) => (<R1>(inclusiveOr: InclusiveOr<L1, R1>) => InclusiveOr<L2, R1 | R2>);
|
|
910
|
+
/**
|
|
911
|
+
* Effectful `mapLeft`: transforms the `left` of an `InclusiveOr` through an `Effect`,
|
|
912
|
+
* leaving any `right` untouched.
|
|
913
|
+
*
|
|
914
|
+
* A specialisation of `mapBothEffect` with the right mapper set to
|
|
915
|
+
* `Effect.succeed`: the `left` (when present) is mapped effectfully and the
|
|
916
|
+
* `right` is carried through unchanged.
|
|
917
|
+
*
|
|
918
|
+
* @example
|
|
919
|
+
* ```ts
|
|
920
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
921
|
+
* import { Effect } from "effect"
|
|
922
|
+
*
|
|
923
|
+
* const inc = InclusiveOr.mapLeftEffect((left: number) => Effect.succeed(left + 1))
|
|
924
|
+
*
|
|
925
|
+
* assert.deepStrictEqual(
|
|
926
|
+
* Effect.runSync(inc(InclusiveOr.LeftAndRight({ left: 1, right: "a" }))),
|
|
927
|
+
* InclusiveOr.LeftAndRight({ left: 2, right: "a" })
|
|
928
|
+
* )
|
|
929
|
+
* ```
|
|
930
|
+
*
|
|
931
|
+
* @category sequencing
|
|
932
|
+
* @since 0.0.0
|
|
933
|
+
*/
|
|
934
|
+
export declare const mapLeftEffect: <L1, L2, EL, RL>(mapLeft: (left: L1) => Effect.Effect<L2, EL, RL>) => (<R>(inclusiveOr: InclusiveOr<L1, R>) => Effect.Effect<InclusiveOr<L2, R>, EL, RL>);
|
|
935
|
+
/**
|
|
936
|
+
* Effectful `flatMapLeft`: chains the `left` of an `InclusiveOr` into an `Effect` that
|
|
937
|
+
* yields a new `InclusiveOr`, flattening the result.
|
|
938
|
+
*
|
|
939
|
+
* When a `left` is present it is passed to `mapLeft`, whose effectful `InclusiveOr`
|
|
940
|
+
* replaces the original; `RightOnly` is lifted unchanged via `Effect.succeed`. Use
|
|
941
|
+
* it to sequence left-driven effectful computations that produce an `InclusiveOr`.
|
|
942
|
+
*
|
|
943
|
+
* @example
|
|
944
|
+
* ```ts
|
|
945
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
946
|
+
* import { Effect } from "effect"
|
|
947
|
+
*
|
|
948
|
+
* const chain = InclusiveOr.flatMapLeftEffect((left: number) =>
|
|
949
|
+
* Effect.succeed(InclusiveOr.LeftOnly({ left: left * 10 }))
|
|
950
|
+
* )
|
|
951
|
+
*
|
|
952
|
+
* assert.deepStrictEqual(
|
|
953
|
+
* Effect.runSync(chain(InclusiveOr.LeftOnly({ left: 2 }))),
|
|
954
|
+
* InclusiveOr.LeftOnly({ left: 20 })
|
|
955
|
+
* )
|
|
956
|
+
* assert.deepStrictEqual(
|
|
957
|
+
* Effect.runSync(chain(InclusiveOr.RightOnly({ right: "a" }))),
|
|
958
|
+
* InclusiveOr.RightOnly({ right: "a" })
|
|
959
|
+
* )
|
|
960
|
+
* ```
|
|
961
|
+
*
|
|
962
|
+
* @category sequencing
|
|
963
|
+
* @since 0.0.0
|
|
964
|
+
*/
|
|
965
|
+
export declare const flatMapLeftEffect: <L1, L2, R2, EL, RL>(mapLeft: (left: L1) => Effect.Effect<InclusiveOr<L2, R2>, EL, RL>) => (<R1>(inclusiveOr: InclusiveOr<L1, R1>) => Effect.Effect<InclusiveOr<L2, R1 | R2>, EL, RL>);
|
|
966
|
+
/**
|
|
967
|
+
* Transforms the `right` of an `InclusiveOr`, leaving any `left` untouched.
|
|
968
|
+
*
|
|
969
|
+
* The mirror of `mapLeft`: `RightOnly` and `LeftAndRight` have their `right`
|
|
970
|
+
* mapped, while `LeftOnly` passes through unchanged.
|
|
971
|
+
*
|
|
972
|
+
* @example
|
|
973
|
+
* ```ts
|
|
974
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
975
|
+
*
|
|
976
|
+
* const upper = InclusiveOr.mapRight((right: string) => right.toUpperCase())
|
|
977
|
+
*
|
|
978
|
+
* assert.deepStrictEqual(
|
|
979
|
+
* upper(InclusiveOr.LeftAndRight({ left: 1, right: "a" })),
|
|
980
|
+
* InclusiveOr.LeftAndRight({ left: 1, right: "A" })
|
|
981
|
+
* )
|
|
982
|
+
* assert.deepStrictEqual(
|
|
983
|
+
* upper(InclusiveOr.LeftOnly({ left: 1 })),
|
|
984
|
+
* InclusiveOr.LeftOnly({ left: 1 })
|
|
985
|
+
* )
|
|
986
|
+
* ```
|
|
987
|
+
*
|
|
988
|
+
* @category mapping
|
|
989
|
+
* @since 0.0.0
|
|
990
|
+
*/
|
|
991
|
+
export declare const mapRight: <R1, R2>(mapRight: (right: R1) => R2) => (<L>(inclusiveOr: InclusiveOr<L, R1>) => InclusiveOr<L, R2>);
|
|
992
|
+
/**
|
|
993
|
+
* Chains the `right` of an `InclusiveOr` into a new `InclusiveOr`, flattening the result.
|
|
994
|
+
*
|
|
995
|
+
* The mirror of `flatMapLeft`: whenever a `right` is present (`RightOnly` or
|
|
996
|
+
* `LeftAndRight`) it is passed to `mapRight`, whose returned `InclusiveOr` replaces the
|
|
997
|
+
* original; `LeftOnly` passes through unchanged.
|
|
998
|
+
*
|
|
999
|
+
* @example
|
|
1000
|
+
* ```ts
|
|
1001
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
1002
|
+
*
|
|
1003
|
+
* const chain = InclusiveOr.flatMapRight((right: string) =>
|
|
1004
|
+
* InclusiveOr.RightOnly({ right: right.toUpperCase() })
|
|
1005
|
+
* )
|
|
1006
|
+
*
|
|
1007
|
+
* assert.deepStrictEqual(
|
|
1008
|
+
* chain(InclusiveOr.RightOnly({ right: "a" })),
|
|
1009
|
+
* InclusiveOr.RightOnly({ right: "A" })
|
|
1010
|
+
* )
|
|
1011
|
+
* assert.deepStrictEqual(
|
|
1012
|
+
* chain(InclusiveOr.LeftOnly({ left: 1 })),
|
|
1013
|
+
* InclusiveOr.LeftOnly({ left: 1 })
|
|
1014
|
+
* )
|
|
1015
|
+
* ```
|
|
1016
|
+
*
|
|
1017
|
+
* @category sequencing
|
|
1018
|
+
* @since 0.0.0
|
|
1019
|
+
*/
|
|
1020
|
+
export declare const flatMapRight: <L2, R1, R2>(mapRight: (right: R1) => InclusiveOr<L2, R2>) => (<L1>(inclusiveOr: InclusiveOr<L1, R1>) => InclusiveOr<L1 | L2, R2>);
|
|
1021
|
+
/**
|
|
1022
|
+
* Effectful `mapRight`: transforms the `right` of an `InclusiveOr` through an `Effect`,
|
|
1023
|
+
* leaving any `left` untouched.
|
|
1024
|
+
*
|
|
1025
|
+
* The mirror of `mapLeftEffect`: the `right` (when present) is mapped effectfully
|
|
1026
|
+
* and the `left` is carried through unchanged via `Effect.succeed`.
|
|
1027
|
+
*
|
|
1028
|
+
* @example
|
|
1029
|
+
* ```ts
|
|
1030
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
1031
|
+
* import { Effect } from "effect"
|
|
1032
|
+
*
|
|
1033
|
+
* const upper = InclusiveOr.mapRightEffect((right: string) =>
|
|
1034
|
+
* Effect.succeed(right.toUpperCase())
|
|
1035
|
+
* )
|
|
1036
|
+
*
|
|
1037
|
+
* assert.deepStrictEqual(
|
|
1038
|
+
* Effect.runSync(upper(InclusiveOr.LeftAndRight({ left: 1, right: "a" }))),
|
|
1039
|
+
* InclusiveOr.LeftAndRight({ left: 1, right: "A" })
|
|
1040
|
+
* )
|
|
1041
|
+
* ```
|
|
1042
|
+
*
|
|
1043
|
+
* @category sequencing
|
|
1044
|
+
* @since 0.0.0
|
|
1045
|
+
*/
|
|
1046
|
+
export declare const mapRightEffect: <R1, R2, ER, RR>(mapRight: (right: R1) => Effect.Effect<R2, ER, RR>) => (<L>(inclusiveOr: InclusiveOr<L, R1>) => Effect.Effect<InclusiveOr<L, R2>, ER, RR>);
|
|
1047
|
+
/**
|
|
1048
|
+
* Effectful `flatMapRight`: chains the `right` of an `InclusiveOr` into an `Effect` that
|
|
1049
|
+
* yields a new `InclusiveOr`, flattening the result.
|
|
1050
|
+
*
|
|
1051
|
+
* The mirror of `flatMapLeftEffect`: when a `right` is present it is passed to
|
|
1052
|
+
* `mapRight`, whose effectful `InclusiveOr` replaces the original; `LeftOnly` is lifted
|
|
1053
|
+
* unchanged via `Effect.succeed`.
|
|
1054
|
+
*
|
|
1055
|
+
* @example
|
|
1056
|
+
* ```ts
|
|
1057
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
1058
|
+
* import { Effect } from "effect"
|
|
1059
|
+
*
|
|
1060
|
+
* const chain = InclusiveOr.flatMapRightEffect((right: string) =>
|
|
1061
|
+
* Effect.succeed(InclusiveOr.RightOnly({ right: right.toUpperCase() }))
|
|
1062
|
+
* )
|
|
1063
|
+
*
|
|
1064
|
+
* assert.deepStrictEqual(
|
|
1065
|
+
* Effect.runSync(chain(InclusiveOr.RightOnly({ right: "a" }))),
|
|
1066
|
+
* InclusiveOr.RightOnly({ right: "A" })
|
|
1067
|
+
* )
|
|
1068
|
+
* assert.deepStrictEqual(
|
|
1069
|
+
* Effect.runSync(chain(InclusiveOr.LeftOnly({ left: 1 }))),
|
|
1070
|
+
* InclusiveOr.LeftOnly({ left: 1 })
|
|
1071
|
+
* )
|
|
1072
|
+
* ```
|
|
1073
|
+
*
|
|
1074
|
+
* @category sequencing
|
|
1075
|
+
* @since 0.0.0
|
|
1076
|
+
*/
|
|
1077
|
+
export declare const flatMapRightEffect: <L2, R1, R2, ER, RR>(mapRight: (right: R1) => Effect.Effect<InclusiveOr<L2, R2>, ER, RR>) => (<L1>(inclusiveOr: InclusiveOr<L1, R1>) => Effect.Effect<InclusiveOr<L1 | L2, R2>, ER, RR>);
|
|
1078
|
+
/**
|
|
1079
|
+
* Zips two arrays into one, calling `f` with an `InclusiveOr` for each index so
|
|
1080
|
+
* that length mismatches are handled explicitly rather than truncated.
|
|
1081
|
+
*
|
|
1082
|
+
* Unlike `Array.zipWith` (which stops at the shorter array), this walks to the
|
|
1083
|
+
* length of the *longer* array. The first array's element fills the `left` side
|
|
1084
|
+
* and the second array's element fills the `right` side, so at each index `f`
|
|
1085
|
+
* receives an `InclusiveOr<A, B>`: `LeftAndRight` when both arrays have an
|
|
1086
|
+
* element, `LeftOnly` when only the first does, and `RightOnly` when only the
|
|
1087
|
+
* second does. Use it when the "extra" tail of either array still carries
|
|
1088
|
+
* meaning.
|
|
1089
|
+
*
|
|
1090
|
+
* @example
|
|
1091
|
+
* ```ts
|
|
1092
|
+
* import { InclusiveOr } from "@nunofyobiz/effect-extras"
|
|
1093
|
+
* import { pipe } from "effect"
|
|
1094
|
+
*
|
|
1095
|
+
* const describe = InclusiveOr.match({
|
|
1096
|
+
* LeftOnly: ({ left }) => `left ${left}`,
|
|
1097
|
+
* RightOnly: ({ right }) => `right ${right}`,
|
|
1098
|
+
* LeftAndRight: ({ left, right }) => `both ${left}/${right}`
|
|
1099
|
+
* })
|
|
1100
|
+
*
|
|
1101
|
+
* // data-first
|
|
1102
|
+
* assert.deepStrictEqual(InclusiveOr.zip([1, 2, 3], [10, 20], describe), [
|
|
1103
|
+
* "both 1/10",
|
|
1104
|
+
* "both 2/20",
|
|
1105
|
+
* "left 3"
|
|
1106
|
+
* ])
|
|
1107
|
+
*
|
|
1108
|
+
* // data-last (pipeable)
|
|
1109
|
+
* assert.deepStrictEqual(pipe([1, 2, 3], InclusiveOr.zip([10, 20], describe)), [
|
|
1110
|
+
* "both 1/10",
|
|
1111
|
+
* "both 2/20",
|
|
1112
|
+
* "left 3"
|
|
1113
|
+
* ])
|
|
1114
|
+
* ```
|
|
1115
|
+
*
|
|
1116
|
+
* @category combinators
|
|
1117
|
+
* @since 0.0.0
|
|
1118
|
+
*/
|
|
1119
|
+
export declare const zip: {
|
|
1120
|
+
<A, B, C>(array2: readonly B[], f: (inclusiveOr: InclusiveOr<A, B>) => C): (array1: readonly A[]) => C[];
|
|
1121
|
+
<A, B, C>(array1: readonly A[], array2: readonly B[], f: (inclusiveOr: InclusiveOr<A, B>) => C): C[];
|
|
1122
|
+
};
|
|
1123
|
+
//# sourceMappingURL=InclusiveOr.d.ts.map
|