monads-lite
v1.2.0
Published
A TypeScript monad library with only the things you'll actually use.
Downloads
7
Maintainers
Readme
monads-lite
A TypeScript monad library with only the things you'll actually use.
Is this you?
I'm a JS/TS developer interested in using some more functional programming patterns in my code, but all these FP libs don't fit with the way I work!
Then mondas-lite is what you need!
monads-lite
is JS/TS library that brings mondic functional programming tools that don't take over your code, and let you expore the benifits functional programming without re-writing your codebase.
Install
npm i monads-lite
Library
Result
The Result<T, E>
type is a monadic construct that can represent the result of an operation which can either succeed or fail.
i.e. type OperationResult = Result.Result<number, 'oh no, I failed'>;
A Result can be infered from a Promise if a error type is provided:
import { Result } from 'monads-lite';
const promise = Promise.resolve(123);
const result: Result<number, CustomErrorType> =
inferFrom(promise).resultify<CustomErrorType>();
A Result can be matched on if it is an Ok or Err:
import { Result } from 'monads-lite';
// This is a powerful tool for program flow control.
const value = Result.match(result, [
(okValue) => handleOk(okValue),
(errValue) => handleErr(errValue),
]);
Actions can be run inside the Result monadic container so that they will only apply if the Result is of type Ok:
import { Result } from 'monads-lite';
const value = Result.act(result, (okValue) => doNextThing(okValue));
These actions can be chained:
import { Result } from 'monads-lite';
const value = Result.onResult(result)
// These actions will only execute if the Result is Ok.
.act(n => n + 1)
.act(n => n * 2)
// Unwrap the value from inside the Result.
.done();
Actions can also be run asynchronously:
import { Result } from 'monads-lite';
const result = await Result.onResult(result)
.actAsync(async (n) => n + 1)
.actAsync(async (n) => n * 2)
.done();
Errors thrown anywhere in the act chain will be resolve out as Err:
import { Result } from 'monads-lite';
const result = Result.onValue<number, Error>(2)
.act((n) => n + 1) // This will run.
.act(() => {
// This will be caught and converted into an Err.
throw new Error('fail 1');
})
.act((n) => n * 2) // This will not run.
.act(() => {
// This will not run.
throw new Error('fail 2');
})
// This unwrap the Result.
.done();
// or
const result = await Result.onValue<number, Error>(2)
.act((n) => n + 1) // This will run.
.act(() => {
// This will be caught and converted into an Err.
throw new Error('fail 1');
})
.act((n) => n * 2) // This will not run.
.actAsync(async () => {
// This will not run.
throw new Error('fail 2');
})
// This unwrap the Result.
.done();
Maybe
The Maybe<A>
type is a monadic construct that can represent a value that is either present or not present.
i.e. type Username = Maybe<string>;
Actions can be run inside the Maybe monadic container so that they will only apply if the Result is of type Ok:
import { Maybe } from 'monads-lite';
const value = Maybe.act(maybe, (existingValue) => doNextThing(existingValue));
These actions can be chained:
import { Maybe } from 'monads-lite';
const value = Maybe.onResult(maybe)
// These actions will only execute if the Result is Ok.
.act(n => n + 1)
.act(n => n * 2)
// Unwrap the value from inside the Result.
.done();
A Maybe can be matched against cases:
import { Maybe } from 'monads-lite';
// If 2, 3 or 9, repeat the digit 5 times.
const value = Maybe.match(maybe, [
n => (n === 2 && (() => 22222)),
n => (n === 3 && (() => 33333)),
n => (n === 9 && (() => 99999)),
]);
When matching a Maybe a default case can also be provided:
import { Maybe } from 'monads-lite';
// If 2, 3 or 9, repeat the digit 5 times,
// otherwise leave value unchanges.
const value = Maybe.match(maybe, [
n => (n === 2 && (() => 22222)),
n => (n === 3 && (() => 33333)),
n => (n === 9 && (() => 99999)),
], n => n);
curry
The curry
function can be used to split a multi-argument function into a nested set of single argument functions. This technique is called currying.
import { curry } from 'monads-lite';
const add = (a: number, b: number, c: number) => {
return a + b + c;
};
const curriedAdd = curry(add);
const addFive = curriedAdd(5);
const addTwenty = addFive(15);
const thirty: number = addTwenty(10);