import { Resume } from '@typed/env' import { Maybe, Nothing, unpack } from '@typed/maybe' import { Capabilities, Effects } from '../Effect' export type FailEnv = { readonly [Key in K]: Fail } export type Fail = (error: Err) => Resume> export const Fail: Fail = (error: any) => Resume.of(Failure.of(error)) export type FailureTypes> = keyof FailuresOf export type FailuresOf> = Pick< Capabilities, FailureKeys> > export type ErrorOf, K extends FailureTypes> = FailuresOf< E >[K] extends Fail ? R : never type FailureKeys = { [K in keyof A]: A[K] extends Fail ? K : never }[keyof A] export class Failure { public static of = (error: Err, value: Maybe = Nothing) => new Failure(error, value) constructor(readonly error: Err, readonly value: Maybe) {} public readonly unpack = (left: (err: Err) => B, right: (value: A) => B): B => unpack(right, () => left(this.error), this.value) }