diff --git a/README.md b/README.md new file mode 100644 index 0000000..1a7d1ba --- /dev/null +++ b/README.md @@ -0,0 +1,75 @@ +# @faergeek/monads + +Easy to use monads for JavaScript and TypeScript. + +Source code itself is pretty small, but it has jsdoc comments, which should +serve as a more complete API documentation: + +- [Maybe](./src/maybe.ts) + + An abstract box representing either presence or absence of a value. + + A box with a value can be created with `Maybe.Some()`. `Maybe.None` + represents an absence of a value. + + Read the comments in source file linked above for details. + +- [Async](./src/async.ts) + + An abstract box representing asynchronous value state. Very similar to + `Maybe`, but has less operations. It exists to make sure that + presence/absence of a value and pending/ready state are easy to tell apart. + Very useful to convey loading state through any value transformations. + + A box with a value ready to be used can be created with + `Async.Ready()`. `Async.Pending` represents a pending state meaning + there's no value yet. + + Read the comments in source file linked above for details. + +- [Result](./src/result.ts) + + An abstract box representing success or failure. + + A box representing success can be created with `Result.Ok()`. + A box representing failure can be created with `Result.Err()`. + + Read the comments in source file linked above for details. + +An example of using both `Async` and `Result` to represent different states of +UI depending on API request result from a hook like SWR or React Query. + +First, we need to create a box, representing 3 states: pending, success and +failure. + +```javascript +// let's assume data is something like a number 21 +const { data, error, isLoading } = useSomeApiHook(); + +const box = data + ? Async.Ready(Result.Ok(data)) + : isLoading + ? Async.Pending + : Async.Ready(Result.Err(error)); +``` + +Apply transformations with `map*` or `flatMap*` functions. + +```javascript +// this will multiply 21 by 2, but only if API request successfully completed +const mapped = box.mapReady(result => result.mapOk(x => x * 2)); +``` + +Use the value, explicitly handling all cases. In this example, we render a UI +using React. + +```javascript +return mapped.match({ + Pending: () => , + Ready: result => + result.match({ + Err: error =>

{error.message}

, + Ok: data =>

{data}

, + }), +}); +```