Skip to content

Instantly share code, notes, and snippets.

@vendethiel
Created December 13, 2023 11:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vendethiel/bf2ff03a1ccc890212edce153a591298 to your computer and use it in GitHub Desktop.
Save vendethiel/bf2ff03a1ccc890212edce153a591298 to your computer and use it in GitHub Desktop.
type Tuple<A, B> = [A, B];
function extractErr<E, R>(r: Result<E, R>): E | undefined {
return r.type === "error" ? r.value : undefined;
}
function composeR<E1, E2, R1, R2>(
r1: Result<E1, R1>,
r2: Result<E2, R2>
): Result<Tuple<E1 | undefined, E2 | undefined>, Tuple<R1, R2>> {
if (r1.type === "error" || r2.type === "error")
return err([extractErr(r1), extractErr(r2)]);
return ok([r1.value, r2.value]);
}
function bimap<E1, E2, R1, R2>(
r: Result<E1, R1>,
l: (err: E1) => E2,
o: (val: R1) => R2
): Result<E2, R2> {
if (r.type === "error") return err(l(r.value));
return ok(o(r.value));
}
function validateNumber(
number: number | undefined
): Result<StateError["number"], number> {
return number === undefined ? err("invalid" as const) : ok(number);
}
function validateName(name: string): Result<StateError["name"], string> {
return name === "" ? err("empty" as const) : ok(name);
}
function specFromState(
state: Op,
duplicates: number[]
): Result<StateError, ValidOp> {
return bimap(
composeR(validateName(state.name), validateNumber(state.number)),
([name, number]) => ({ name, number } as const),
([name, number]) => ({ name, number, description: "" } as const)
);
}
function oldSpecFromState(
state: Op,
duplicates: number[]
): Result<StateError, ValidOp> {
const errors: StateError = {};
const validated: Partial<ValidOp> = {};
if (state.number === undefined) {
errors.number = "invalid";
} else {
validated.number = state.number;
}
return Object.keys(errors).length > 0
? err(errors)
: (ok(validated) as Ok<ValidOp>);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment