roption-js
Rusty Monad Options for JS
Everyone knows that when dealing with data, sometimes there is nothing to pass or nothing to return.
Usually, in JS, we have to decide for either undefined
or null
, but also sometimes NaN
and similar.
In order to simplify this problem, monadic options were created, which can either contain a value, or not.
One of the most prominent usages of such an option system is core::option::Option
of the programming language Rust.
This module is based on the Rust implementation, but brings some changes in order to better use it in JS.
One of the major differences is that option-js uses lowerCamelCase instead of snake_case.
Additionally, the methods involving std::result::Result
were not implemented, since they require a Result-dependency.
roption-js
does not have any dependencies and conducts unit tests and coverage with TAP
and coveralls
.
You can find the complete API, as defined in code, below the examples!
Installation
npm i roption-js --save
Simple Example
In the following example, you can see that the traditional way needs a lot more LoC and might lead to errors. The Option Monad helps to clean this mess up!
For more simple examples, please take a look at ./test.js
, on which Travis CI and Coveralls tests are based!
'use strict'; // Traditional way ; // -------------------------------------// With Option const Option = ; ;
Usage
Create new Result
'use strict'; const Option = ; const hasSome = Option;const hasNone = Option; // ...
Register Some() and None()
// ... // After the following line, Some() and None() will be available on a global level.// That means that you can do stuff, like// return Some(val);// return None();Option; // ...
Check if contains value
// ... if hasSome || !hasSome console; if hasNone || !hasNone console; // ...
Get Value
// ... // `unwrap` will throw if the Option is Nonevar myResult = hasSome; // `expect` will also throw if the Option is None, but add a messagemyResult = hasSome; // `and` will return the passed value instead of the Some-value if the Option is not NonemyResult = hasSome;myResult = hasSome; // `or` will return the passed value in case the Option is NonemyResult = hasNone;myResult = hasNone; // Or just a very simple matchhasNone;
API
All methods work just as described in the Rust documentation. The interface below includes Exceptions, however all methods are fully implemented and will not throw. The Exceptions are in place in order to provide you a clear, non-cluttered API overview.
/** * Rusty Monad Options for JS * * @type */moduleexports = /** * Construct a new Option Object from a value as Some(value) * If no value is passed, the option will contain None * * @param * @param */ { this; }; /** * Create Some(val) * * @param * @returns */ static { return true val; }; /** * Create None * * @returns */ static { return false null; }; /** * Create an Option from a value. * An algorithm takes a guess if it should be a Some or a None. * Empty arrays will be transformed to None * * @param * @returns */ static { throw 'Not Implemented: Option.fromGuess'; }; /** * Register Some and None on a global scope */ static { throw 'Not Implemented: Option.registerGlobals'; }; /** * Returns true if the option is a Some value. * * @returns */ { throw 'Not Implemented: Option.isSome'; }; /** * Returns true if the option is a None value. * * @returns */ { throw 'Not Implemented: Option.isNone'; }; /** * Unwraps an option, yielding the content of a Some. * * @throws if the value is a None with a custom panic message provided by msg. * @param * @returns */ { throw 'Not Implemented: Option.expect'; }; /** * Moves the value v out of the Option<T> if it is Some(v). * In general, because this function may panic, its use is discouraged. * Instead, prefer to use pattern matching and handle the None case explicitly. * * @throws if the self value equals None. * @returns */ { throw 'Not Implemented: Option.unwrap'; }; /** * Maps an Option<T> to Option<U> by applying a function to a contained value. * * @param * @returns */ { throw 'Not Implemented: Option.map'; }; /** * Returns an iterator over the possibly contained value. * * @returns {Iterable.<*>} */ { throw 'Not Implemented: Option.iter'; }; /** * Returns None if the option is None, otherwise returns optb. * * @param * @returns */ { throw 'Not Implemented: Option.and'; }; /** * Returns None if the option is None, otherwise calls f with the wrapped value and returns the result. * * @param * @returns */ { throw 'Not Implemented: Option.andThen'; }; /** * Returns the option if it contains a value, otherwise returns optb. * * @param * @returns */ { throw 'Not Implemented: Option.or'; }; /** * Returns the option if it contains a value, otherwise calls f and returns the result. * * @param * @returns */ { throw 'Not Implemented: Option.orElse'; }; /** * Takes the value out of the option, leaving a None in its place. * * @returns */ { throw 'Not Implemented: Option.isSome'; }; /** * JS convenience method then-like handler for pattern-matching * * @param * @param */ { throw 'Not Implemented: Option.match'; }; /** * JS convenience method to handle a result NodeJS-style * Example: * Option.fromNone().node((err, val) => { * // do sth. * }); * * @param */ { throw 'Not Implemented: Option.node'; };; /** * This Callback is used to map over an Option * * @callback OptionMap * @param * `val` will contain the Some-part of {Option}. * @returns */ /** * This Callback is used to handle andThen calls * * @callback OptionAndThenHandler * @param * `val` will contain the Some-part of {Option}. * @returns */ /** * This Callback is used to handle orElse calls * It has to generate a new value * * @callback OptionOrElseHandler * @returns */ /** * This Callback is used to handle pattern-matching calls * * @callback OptionSomeHandler * @param * `val` will contain the Some-part of {Option}. * @returns */ /** * This Callback is used to handle pattern-matching calls * * @callback OptionNoneHandler * @returns */ /** * This callback is used as NodeJS-style handler * * @callback OptionNodeJSStyleHandler * @oaram * @param */