An educational pure functional programming library in TypeScript
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 90 lines 2.3 kB view raw
1import { match } from "../prelude/match" 2 3/** 4 * Exit represents the result of an effect execution. 5 * Three variants: Success, Failure, or Interrupted. 6 */ 7export type Exit<A, E> = 8 | { readonly _tag: "Success"; readonly value: A } 9 | { readonly _tag: "Failure"; readonly error: E } 10 | { readonly _tag: "Interrupted"; readonly by: string } 11 12// Constructors 13export const success = <A>(value: A): Exit<A, never> => ({ 14 _tag: "Success", 15 value, 16}) 17 18export const failure = <E>(error: E): Exit<never, E> => ({ 19 _tag: "Failure", 20 error, 21}) 22 23export const interrupted = (by: string): Exit<never, never> => ({ 24 _tag: "Interrupted", 25 by, 26}) 27 28// Type guards 29export const isSuccess = <A, E>( 30 exit: Exit<A, E>, 31): exit is Extract<Exit<A, E>, { _tag: "Success" }> => exit._tag === "Success" 32 33export const isFailure = <A, E>( 34 exit: Exit<A, E>, 35): exit is Extract<Exit<A, E>, { _tag: "Failure" }> => exit._tag === "Failure" 36 37export const isInterrupted = <A, E>( 38 exit: Exit<A, E>, 39): exit is Extract<Exit<A, E>, { _tag: "Interrupted" }> => 40 exit._tag === "Interrupted" 41 42// Match helper 43export const matchExit = 44 <A, E, R>( 45 onSuccess: (value: A) => R, 46 onFailure: (error: E) => R, 47 onInterrupted: (by: string) => R, 48 ) => 49 (exit: Exit<A, E>): R => 50 match(exit)({ 51 Success: ({ value }) => onSuccess(value), 52 Failure: ({ error }) => onFailure(error), 53 Interrupted: ({ by }) => onInterrupted(by), 54 }) 55 56/** 57 * Transform both success and failure values of an Exit (Bifunctor). 58 * Interrupted exits pass through unchanged. 59 * 60 * @example 61 * ```typescript 62 * pipe( 63 * success(10), 64 * bimapExit( 65 * n => n * 2, // transform Success 66 * e => e.toUpperCase() // transform Failure 67 * ) 68 * ) // Success(20) 69 * ``` 70 */ 71export const bimapExit = 72 <A, B, E, F>(onSuccess: (a: A) => B, onFailure: (e: E) => F) => 73 (exit: Exit<A, E>): Exit<B, F> => 74 exit._tag === "Success" 75 ? success(onSuccess(exit.value)) 76 : exit._tag === "Failure" 77 ? failure(onFailure(exit.error)) 78 : interrupted(exit.by) 79 80// Namespace for convenient dotted access to the Exit API. 81export const Exit = { 82 success, 83 failure, 84 interrupted, 85 isSuccess, 86 isFailure, 87 isInterrupted, 88 match: matchExit, 89 bimap: bimapExit, 90}