// Core types
type Result<A, E = never> = Success<A, E> | Failure<A, E>
interface Success<A, E> {
readonly _tag: "Success"
readonly success: A
}
interface Failure<A, E> {
readonly _tag: "Failure"
readonly failure: E
}
// Creation
const succeed: <A>(right: A) => Result<A>
const fail: <E>(left: E) => Result<never, E>
const try: {
<A, E>(options: {
readonly try: () => A
readonly catch: (error: unknown) => E
}): Result<A, E>
<A>(evaluate: () => A): Result<A, unknown>
}
// Guards
const isResult: (input: unknown) => input is Result<unknown, unknown>
const isSuccess: <A, E>(self: Result<A, E>) => self is Success<A, E>
const isFailure: <A, E>(self: Result<A, E>) => self is Failure<A, E>
// Transform
const map: {
<A, A2>(f: (ok: A) => A2): <E>(self: Result<A, E>) => Result<A2, E>
<A, E, A2>(self: Result<A, E>, f: (ok: A) => A2): Result<A2, E>
}
const mapError: {
<E, E2>(f: (err: E) => E2): <A>(self: Result<A, E>) => Result<A, E2>
<A, E, E2>(self: Result<A, E>, f: (err: E) => E2): Result<A, E2>
}
// Chain
const flatMap: {
<A, A2, E2>(f: (a: A) => Result<A2, E2>): <E>(self: Result<A, E>) => Result<A2, E | E2>
<A, E, A2, E2>(self: Result<A, E>, f: (a: A) => Result<A2, E2>): Result<A2, E | E2>
}
// Unwrap
const getOrElse: {
<E, A2>(onFailure: (err: E) => A2): <A>(self: Result<A, E>) => A2 | A
<A, E, A2>(self: Result<A, E>, onFailure: (err: E) => A2): A | A2
}
const getOrThrow: <A, E>(self: Result<A, E>) => A
// Match
const match: {
<E, B, A, C = B>(options: {
readonly onFailure: (error: E) => B
readonly onSuccess: (ok: A) => C
}): (self: Result<A, E>) => B | C
}