tryad ·
Monadic mashup of Maybe & Either that represents a value, nothing, or an error.
There are a few major reasons for tryad
to exist:
- most existing Maybe / Option / Either / Result types in JavaScript don't seamlessly interop with Promises
- if the Maybe contains an array, you have to
map
inside amap
because it doesn't dispatch toMaybe
andtoEither
become unnecessary if the type simply has a third branch to cover exceptions
So tryad
attempts to create a new type that incorporates all of this - replacing
both null
-ish checks and try
/catch
while working well with Promises.
installation
npm i tryad
usage
const loadPlugin = { return } const plugin = name: 'a-plugin' /*, path: './plugin.js' */ const loaded = // in this case `path` is not defined, so we get a `None`:// -> 'plugin.path was not defined, so nothing was executed'
Or if you're all about that async, let's check out Promises!
;async { const result = await // returning a Promise here like `readJson` does // makes the chain's result become asynchronous // methods dispatch to the inner value, so this // maps over each keyword in the array /*...*/}
And remember that if at any point a transformation causes a nil / falsy value
to be returned or if .try()
throws an Error, the following transformations
will not be executed. This makes null handling very easy - in this case
the chain would 'skip forward' to the unwrap
call.
api
tryad
Returns a new object that is either a None
if value == null
or a Some
containing value
otherwise.
Expand the following sections to see the full documentation.
static methods
of
tryad
Alternate constructor that checks for truthiness rather than loose equality to null
.
try
tryad
Shortcut for tryad.of(value).try(fn)
. If value != null
it will be applied
to the function fn
, and any errors will be caught to transform the tryad
into a Fail
. fn
is only executed on a Some
.
Arguments
-
value: any
-
fn: value -> any
Function that will receive
value
as its only parameter. All errors are caught and returned in a newFail
object.
Returns
Some | None | Fail
async
tryad
Asynchronous version of the tryad
constructor that accepts value
as a
Promise, or wraps it in one if it isn't already a Promise.
async.of
tryadasync
Asynchronous version of the tryad.of
constructor that accepts value
as a
Promise, or wraps it in one if it isn't already a Promise.
isSomeLike
tryad
Useful for checking if an arbitrary object is a Some
, meaning
it is not == null
and has an isSome
method that returns true
.
Arguments
value: any
Returns
Boolean
isNoneLike
tryad
Useful for checking if an arbitrary object is a None
, meaning
it is not == null
and has an isNone
method that returns true
.
Arguments
value: any
Returns
Boolean
isFailLike
tryad
Useful for checking if an arbitrary object is a Fail
, meaning
it is not == null
and has an isFail
method that returns true
.
Arguments
value: any
Returns
Boolean
instance methods
These methods are callable on instances of a Some
, None
, or Fail
.
Examples will use the name box
to represent one of these instances.
filter
box
fn
will only be executed if box
is a Some
, and receives its value as its
only argument. If it returns falsy, a None
will be returned. If it returns
truthy, the current instance is returned as-is. Dispatches to value.filter()
if it is callable.
Arguments
fn: (value) -> Boolean
Returns
Some | None
flatMap
box
fn
will only be executed if box
is a Some
, and receives its value as its
only argument. Any returned tryad
will be absorbed. Dispatches to value.flatMap()
if it is callable.
Arguments
fn: (value) -> Some | None | Fail
Returns
Some | None | Fail
forEach
box
fn
will only be executed if box
is a Some
, and receives its value as its
only argument. This method ends the chain. Dispatches to value.forEach()
if
it is callable.
Arguments
fn: (value) -> any
Returns
undefined
includes
box
If box
is a Some, compares other
against the value contained within box
and returns true
if they are equal. Returns false
if box
is not a Some
.
Dispatches to value.includes()
if it is callable.
Returns
Boolean
map
box
fn
will only be executed if box
is a Some
, and receives its value as its
only argument. The return value will be used to construct a new tryad
. If
fn
will return a tryad
, you probably want to use flatMap
instead.
Dispatches to value.map()
if it is callable.
Arguments
fn: (value) -> any
Returns
Some | None
orElse
box
fn
is only called if box
is a None
or a Fail
. If box
is a Fail
,
fn
will receive the error contained within.
Arguments
fn: (error?) -> any
Returns
Some | any
orSome
box
Returns the value contained within box
if it is a Some
, or returns
other
if it is a None
or a Fail
. This method ends the chain.
Arguments
other: any
Returns
any
some
box
Returns the value contained within box
. Throws if box
is not a Some
, so it's safer to use orSome
. This method ends the chain.
Returns
any
try
box
Attempts to call fn(value)
and catches any error that occurs, returning a
Fail
with the error. Not executed if box
is not a Some
.
Arguments
fn: value -> Some | None | Fail
Returns
Some | None | Fail
unwrap
box
Calls whichever function corresponds to the instance type and returns its value.
Arguments
ifSome: value -> any
ifNone: () -> any
ifFail: error -> any
Returns
any
see also
param.macro
- Babel plugin for compile time partial application & lambda parameters
contributing
Pull requests and any issues found are always welcome.
- Fork the project, and preferably create a branch named something like
feat-make-better
- Modify the source files as needed
- Make sure all tests continue to pass, and it never hurts to have more tests
- Push & pull request! 🎉
license
MIT © Bo Lingen / citycide