Skip to content

Instantly share code, notes, and snippets.

@JLarky
Last active Oct 27, 2020
Embed
What would you like to do?
export type Left<L> = { left: L };
export type Right<R> = { right: R };
export type Either<L, R> = Left<L> | Right<R>;
export function isLeft<L, R>(value: Either<L, R>): value is Left<L> {
return "left" in value;
}
export function isRight<L, R>(value: Either<L, R>): value is Right<R> {
return "right" in value;
}
export function Left<L>(left: L): Left<L> {
return { left };
}
export function Right<R>(right: R): Right<R> {
return { right };
}
export function fromLeft<L, R, DV>(value: Left<L>, defaultValue: DV): Left<L>;
export function fromLeft<L, R, DV>(value: Right<R>, defaultValue: DV): DV;
export function fromLeft<L, R, DV>(value: Either<L, R>, defaultValue: DV): Left<L> | DV;
export function fromLeft<L, R, DV>(value: Either<L, R>, defaultValue: DV) {
return isLeft(value) ? value.left : defaultValue;
}
export function fromRight<L, R, DV>(value: Right<R>, defaultValue: DV): Right<R>;
export function fromRight<L, R, DV>(value: Left<L>, defaultValue: DV): DV;
export function fromRight<L, R, DV>(value: Either<L, R>, defaultValue: DV): Right<R> | DV;
export function fromRight<L, R, DV>(value: Either<L, R>, defaultValue: DV) {
return isRight(value) ? value.right : defaultValue;
}
export type Left<L> = { left: L };
export type Right<R> = { right: R };
export type Either<L, R> = Left<L> | Right<R>;
export function isLeft<L, R>(value: Either<L, R>): value is Left<L> {
return "left" in value;
}
export function isRight<L, R>(value: Either<L, R>): value is Right<R> {
return "right" in value;
}
export function Left<L>(left: L): Left<L> {
return { left };
}
export function Right<R>(right: R): Right<R> {
return { right };
}
export function fromLeft<L, R, DV>(value: Either<L, R>, defaultValue: DV) {
return isLeft(value) ? value.left : defaultValue;
}
export function fromRight<L, R, DV>(value: Either<L, R>, defaultValue: DV) {
return isRight(value) ? value.right : defaultValue;
}
export type Left<L> = ["left", L];
export type Right<R> = ["right", R];
export type Either<L, R> = Left<L> | Right<R>;
export function isLeft<L, R>(value: Either<L, R>): value is Left<L> {
return value[0] === "left";
}
export function isRight<L, R>(value: Either<L, R>): value is Right<R> {
return value[0] === "right";
}
export function Left<L>(left: L): Left<L> {
return ["left", left];
}
export function Right<R>(right: R): Right<R> {
return ["right", right];
}
export function fromLeft<L, R, DV>(value: Either<L, R>, defaultValue: DV) {
return value[0] === "left" ? value[1] : defaultValue;
}
export function fromRight<L, R, DV>(value: Either<L, R>, defaultValue: DV) {
return value[0] === "right" ? value[1] : defaultValue;
}
type Hackathon = {
name: string;
endDate: number; // UNIX epoch timestamp
startDate: number;
};
type MyError = string;
type Predicate<N> = (val: N) => boolean;
function firstLeft<A, B>(val: B, predicatePairs: [Predicate<B>, A][]): Either<A, B> {
for (let i = 0; i < predicatePairs.length; i++) {
const [p, e] = predicatePairs[i];
if (!p(val)) return Left(e);
}
return Right(val);
}
const StartDateMustBePositive = (h: Hackathon) => h.startDate > 0;
const EndDateMustBePositive = (h: Hackathon) => h.endDate > 0;
const HackathonSpec: [Predicate<Hackathon>, MyError][] = [
[StartDateMustBePositive, "Start Date must be positive!"],
[EndDateMustBePositive, "End Date must be positive!"],
];
function validateHackathon(h: Hackathon): Either<MyError, Hackathon> {
return firstLeft(h, HackathonSpec);
}
const x = validateHackathon({} as any);
if (isLeft(x)) {
const rUndefined = fromRight(x, undefined);
const rLeft = fromLeft(x, undefined);
const rValue = x.left;
} else {
const rRight = fromRight(x, undefined);
const rUndefined = fromLeft(x, undefined);
const rValue = x.right;
}
// unfortunatelly this doesn't work, in ideal world you would see type Either but instead it shows it as Either | undefined
const z = fromRight(x, fromLeft(x, undefined));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment