Maybe monad for JavaScript
npm install maybe-baby> 2.x will be maintained, however, if possible for your repository, you should opt to use TypeScript's optional chaining, which was introduced in 3.7
- Install
- Getting Started
- Docs
- Migration
- API
- of
- isJust
- isNothing
- join
- orElse
- map
- chain
- Credit
* npm install --save maybe-baby
* yarn add maybe-baby
---
What if we need the zipCode of the user below, which lives on the address object?
``javascript`
const user = {
email: 'foo@bar.com',
address: null,
name: {
first: 'John',
last: null,
middle: null
}
};
Accessing it via dot notation will result in an error:
`javascript`
const zipCode = user.address.zipCode; // Uncaught TypeError: Cannot read property 'zipCode' of undefined
1. Write some ugly null checks that don't scale well:
`javascript`
const getZipCode = (user) => {
if (user !== null && user !== undefined) {
if (user.address !== null && user.address !== undefined) {
return user.address.zipCode
}
}
}
2. Use _.get() or something similar, but these libraries have large footprints, and most likely won't be implementing the monadic structure.
3. Wait for optional chaining to be approved in ECMA, or use babel-plugin-transform-optional-chaining.
4. Use TypeScript's optional chaining
1. Use maybe-baby to minimize defensive coding:
`javascript
import Maybe from 'maybe-baby';
// Use a function getter
const getZipCode = (user) => Maybe.of(() => user.address.zipCode).join();
`
Now we can safely get the zipCode without worrying about the shape of the object, or encountering TypeErrors:
`js`
const zipCode = getZipCode(user);
console.log(zipCode); // undefined
----
Documentation generated via JSDoc.
* https://mikechabot.github.io/maybe-baby/
---
Breaking changes were introduced in 2.0.0; the following redundant function were removed.
> Maybe.of(, props, and path.
`javascript
const obj = Maybe.of({
foo: {
bar: [123, 456]
}
});
// Incorrect
const bar = obj.prop("foo").join(); // { bar: [123, 456] }
// Correct
Maybe.of(() => obj.join().foo).join(); // { bar: [123, 456] }
// Incorrect
obj
.prop("foo")
.prop("bar")
.prop(1)
.join(); // 456
// Correct
Maybe.of(() => obj.join().foo.bar[1]).join() // 456
`
`javascript
const obj = Maybe.of({
foo: 'bar',
baz: [1,2,3]
});
// Incorrect
obj.props('baz', 0).join(); // 1
// Correct
Maybe.of(() => obj.join().baz[0]).join(); // 1
`
`javascript
const obj = Maybe.of({
foo: 'bar',
baz: [1,2,3]
});
// Incorrect
obj.path('baz.0').join() // 1
// Correct
Maybe.of(() => obj.join().baz[0]).join(); // 1
`
---
Check out the API below, or the complete documentation.
Accepts a value of any type, and returns a monad:
`javascript`
const str = Maybe.of('foo');
const num = Maybe.of(123);
const bool = Maybe.of(true);
const obj = Maybe.of({});
const arr = Maybe.of([]);
const empty = Maybe.of(null);
const undef = Maybe.of(undefined);
Accepts a function, and sets the function's return value as the monad's value, returns a monad.
> If the function results in an error, the monad's value is set to undefined.
`typescript
type OfTypeFunc
const user = {};
const mZipCode = Maybe.of(() => user.address.zipCode);
console.log(mZipCode.join()); // undefined
`
----
Returns true if the value is not null or undefined:
`javascript`
Maybe.of(123).isJust(); // true
Maybe.of(null).isJust(); // false
----
Returns true if the value is null or undefined:
`javascript`
Maybe.of(123).isNothing(); // false
Maybe.of(null).isNothing(); // true
----
Returns the value:
`javascript`
Maybe.of(123).join(); // 123
Maybe.of(null).join(); // null
----
Chain to the end of a monad to return as the default value if isNothing() is true:
`javascript`
Maybe.of(undefined)
.orElse('No Value')
.join(); // 'No Value'
----
Apply a transformation to the monad, and return a new monad:
`javascript
const val = 1;
const newVal = Maybe.of(val).map(val => val + 1);
newVal.join(); // 2;
`
----
Chain together functions that return Maybe monads:
`javascript
function addOne (val) {
return Maybe.of(val + 1);
}
const three = Maybe.of(1)
.chain(addOne)
.chain(addOne);
three.join(); // 3
``
----
Credit to James Sinclair for writing The Marvellously Mysterious JavaScript Maybe Monad.