An educational pure functional programming library in TypeScript
2
fork

Configure Feed

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

Add prelude/result module with Result type and operations

+51
+1
src/prelude/index.ts
··· 1 1 export * from "./compose" 2 + export * from "./result"
+50
src/prelude/result.ts
··· 1 + // Result type for error handling as values 2 + 3 + // Types 4 + export type Ok<T> = { readonly _tag: "Ok"; readonly value: T } 5 + export type Err<E> = { readonly _tag: "Err"; readonly error: E } 6 + export type Result<T, E> = Ok<T> | Err<E> 7 + 8 + // Constructors 9 + export const ok = <T>(value: T): Ok<T> => ({ _tag: "Ok", value }) 10 + export const err = <E>(error: E): Err<E> => ({ _tag: "Err", error }) 11 + 12 + // Type guards 13 + export const isOk = <T, E>(r: Result<T, E>): r is Ok<T> => r._tag === "Ok" 14 + export const isErr = <T, E>(r: Result<T, E>): r is Err<E> => r._tag === "Err" 15 + 16 + // Operations - expression only, no early returns 17 + export const mapResult = <T, U, E>(f: (t: T) => U) => 18 + (result: Result<T, E>): Result<U, E> => 19 + result._tag === "Ok" ? ok(f(result.value)) : result 20 + 21 + export const mapErr = <T, E, F>(f: (e: E) => F) => 22 + (result: Result<T, E>): Result<T, F> => 23 + result._tag === "Err" ? err(f(result.error)) : result 24 + 25 + export const chainResult = <T, U, E>(f: (t: T) => Result<U, E>) => 26 + (result: Result<T, E>): Result<U, E> => 27 + result._tag === "Ok" ? f(result.value) : result 28 + 29 + export const unwrapOr = <T, E>(defaultValue: T) => 30 + (result: Result<T, E>): T => 31 + result._tag === "Ok" ? result.value : defaultValue 32 + 33 + export const matchResult = <T, E, R>( 34 + onOk: (value: T) => R, 35 + onErr: (error: E) => R 36 + ) => (result: Result<T, E>): R => 37 + result._tag === "Ok" ? onOk(result.value) : onErr(result.error) 38 + 39 + /** 40 + * ESCAPE HATCH: Catches JavaScript exceptions at the boundary. 41 + * JS uses exceptions for errors, but FP uses Result. This bridges that gap. 42 + * Inside purus, we use Result - this is only for external JS interop. 43 + */ 44 + export const tryCatch = <T>(f: () => T): Result<T, unknown> => { 45 + try { 46 + return ok(f()) 47 + } catch (e) { 48 + return err(e) 49 + } 50 + }