summaryrefslogtreecommitdiff
path: root/u/fn/either.ts
diff options
context:
space:
mode:
Diffstat (limited to 'u/fn/either.ts')
-rw-r--r--u/fn/either.ts28
1 files changed, 22 insertions, 6 deletions
diff --git a/u/fn/either.ts b/u/fn/either.ts
index 916bb71..9dc1027 100644
--- a/u/fn/either.ts
+++ b/u/fn/either.ts
@@ -1,10 +1,16 @@
-import type { Mapper, Supplier } from "@emprespresso/pengueno";
+import type { BiMapper, Mapper, Supplier } from "@emprespresso/pengueno";
+import { isObject } from "../leftpadesque/mod.ts";
+
+type IEitherTag = "IEither";
+const iEitherTag: IEitherTag = "IEither";
export interface IEither<E, T> {
+ readonly _tag: IEitherTag;
mapBoth: <Ee, Tt>(
errBranch: Mapper<E, Ee>,
okBranch: Mapper<T, Tt>,
) => IEither<Ee, Tt>;
+ fold: <Tt>(folder: BiMapper<E | null, T | null, Tt>) => Tt;
moveRight: <Tt>(t: Tt) => IEither<E, Tt>;
mapRight: <Tt>(mapper: Mapper<T, Tt>) => IEither<E, Tt>;
mapLeft: <Ee>(mapper: Mapper<E, Ee>) => IEither<Ee, T>;
@@ -15,14 +21,20 @@ export interface IEither<E, T> {
}
export class Either<E, T> implements IEither<E, T> {
- private constructor(private readonly err?: E, private readonly ok?: T) {}
+ private constructor(
+ private readonly err?: E,
+ private readonly ok?: T,
+ public readonly _tag: IEitherTag = iEitherTag,
+ ) {}
- public moveRight<Tt>(
- t: Tt,
- ) {
+ public moveRight<Tt>(t: Tt) {
return this.mapRight(() => t);
}
+ public fold<R>(folder: BiMapper<E | null, T | null, R>): R {
+ return folder(this.err ?? null, this.ok ?? null);
+ }
+
public mapBoth<Ee, Tt>(
errBranch: Mapper<E, Ee>,
okBranch: Mapper<T, Tt>,
@@ -37,7 +49,7 @@ export class Either<E, T> implements IEither<E, T> {
}
public mapRight<Tt>(mapper: Mapper<T, Tt>): IEither<E, Tt> {
- if (this.ok !== undefined) return Either.right(mapper(this.ok));
+ if (this.ok !== undefined) return Either.right<E, Tt>(mapper(this.ok));
return Either.left<E, Tt>(this.err!);
}
@@ -79,3 +91,7 @@ export class Either<E, T> implements IEither<E, T> {
}
}
}
+
+export const isEither = <E, T>(o: unknown): o is IEither<E, T> => {
+ return isObject(o) && "_tag" in o && o._tag === "IEither";
+};