summaryrefslogtreecommitdiff
path: root/u/fn/either.ts
diff options
context:
space:
mode:
authorElizabeth Hunt <lizhunt@amazon.com>2025-05-13 18:58:45 -0700
committerElizabeth Hunt <lizhunt@amazon.com>2025-05-13 18:58:54 -0700
commit1d66a0f58e4ebcdf4f42c9d78f82a1ab49a2cf11 (patch)
tree07073c060b61688e4635fd4658315cc683589d3d /u/fn/either.ts
parent2543ac8b11af11f034836591046cdb52911f9403 (diff)
downloadci-1d66a0f58e4ebcdf4f42c9d78f82a1ab49a2cf11.tar.gz
ci-1d66a0f58e4ebcdf4f42c9d78f82a1ab49a2cf11.zip
snapshot!
Diffstat (limited to 'u/fn/either.ts')
-rw-r--r--u/fn/either.ts62
1 files changed, 62 insertions, 0 deletions
diff --git a/u/fn/either.ts b/u/fn/either.ts
new file mode 100644
index 0000000..eaf77fd
--- /dev/null
+++ b/u/fn/either.ts
@@ -0,0 +1,62 @@
+import type { Mapper, Supplier } from "./mod.ts";
+
+export interface IEither<E, T> {
+ mapBoth: <Ee, Tt>(
+ errBranch: Mapper<E, Ee>,
+ okBranch: Mapper<T, Tt>,
+ ) => IEither<Ee, Tt>;
+ flatMap: <Tt>(mapper: Mapper<T, IEither<E, Tt>>) => IEither<E, Tt>;
+ mapRight: <Tt>(mapper: Mapper<T, Tt>) => IEither<E, Tt>;
+ mapLeft: <Ee>(mapper: Mapper<E, Ee>) => IEither<Ee, T>;
+}
+
+export class Either<E, T> implements IEither<E, T> {
+ private constructor(private readonly err?: E, private readonly ok?: T) {}
+
+ public mapBoth<Ee, Tt>(
+ errBranch: Mapper<E, Ee>,
+ okBranch: Mapper<T, Tt>,
+ ): Either<Ee, Tt> {
+ if (this.err) return Either.left(errBranch(this.err));
+ return Either.right(okBranch(this.ok!));
+ }
+
+ public flatMap<Tt>(mapper: Mapper<T, Either<E, Tt>>) {
+ if (this.ok) return mapper(this.ok);
+ return Either.left<E, Tt>(this.err!);
+ }
+
+ public mapRight<Tt>(mapper: Mapper<T, Tt>): IEither<E, Tt> {
+ if (this.ok) return Either.right(mapper(this.ok));
+ return Either.left<E, Tt>(this.err!);
+ }
+
+ public mapLeft<Ee>(mapper: Mapper<E, Ee>) {
+ if (this.err) return Either.left<Ee, T>(mapper(this.err));
+ return Either.right<Ee, T>(this.ok!);
+ }
+
+ static left<E, T>(e: E) {
+ return new Either<E, T>(e);
+ }
+
+ static right<E, T>(t: T) {
+ return new Either<E, T>(undefined, t);
+ }
+
+ static fromFailable<E, T>(s: Supplier<T>) {
+ try {
+ return Either.right<E, T>(s());
+ } catch (e) {
+ return Either.left<E, T>(e as E);
+ }
+ }
+
+ static async fromFailableAsync<E, T>(s: Promise<T>) {
+ try {
+ return Either.right<E, T>(await s);
+ } catch (e) {
+ return Either.left<E, T>(e as E);
+ }
+ }
+}