npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

option-monad

v1.5.1

Published

Option monad implementation for JS

Downloads

33

Readme

JavaScript Option monad type

NPM Build Status

This adds an Option monad type for JavaScript.

The Option type is intended for cases where you sometimes might return a value (typically an object), and sometimes you might return no value (typically null) depending on arguments, or other runtime factors.

On one hand, the Option type forces a developer to consciously think about both cases (returning a value, or returning no value). That in itself will already make your code more robust. On the other hand, the Option type also allows the API developer to provide more concise API methods, and empowers the API user in how he consumes these methods.

Installation

Module can be easily installed with NPM:

npm install --save option-monad

Usage

Simply require it in your code:

const { Option } = require("option-monad");

Module consists of Option facade function, and two concrete variants of an Option: Some and None constructors. Option type supports chaining of the standard set of transformations:

  • map(func: Any => Any): Option
  • flatMap(func: Any => Option): Option
  • filter(func: Any => Boolean): Option
  • filterNot(func: Any => Boolean): Option
  • select(val: Any): Option
  • reject(val: Any): Option
  • foldLeft(initial: T, func: Any => T): T
  • foldRight(initial: T, func: Any => T): T

It also has two methods for querying:

  • isDefined(): Boolean
  • isEmpty(): Boolean

Keep in mind, that not any of those methods will mutate the Option instance they were called on.

'Option' facade function

Offers singular entry point to work with options. It is worth remembering that this is not a constructor, so it will throw Error when called with a new operator.

Function signature is:

function Option(value, noneValue = null) { ... }

, where value is the value, that is going to be stored in an Option. You can also supply value to the noneValue argument that will be used as a criteria of the None case.

'LazyOption' type

Offers a lazy zounterpart for the Option type. Takes a callback and a set of arguments to apply to it. Will internally store those, up until the computation of the option result is required. Callback should return an instance of Option (and, potentially, can return another LazyOption).

IS a constructor. But possesses create static method to create it's instance. IS an Iterable.

Possesses all of the Option type's transformation and query methods (those are mapped to internal Option that is a result of the callback computation), plus it's own isResolved method that exposes it's internal state.

Example:

let resultOne = Option(1);        // will result in a Some instance
let resultTwo = Option(2, 2);     // will result in a None instance

Both "Some", "None", and "LazyOption" instances are also considered instances of the "Option" type:

let someOpt = Option("value");

console.log(someOpt instanceof Some);       // true
console.log(someOpt instanceof Option);     // true

or

let noneOpt = Option(null);

console.log(noneOpt instanceof None);       // true
console.log(noneOpt instanceof Option);     // true

or

let lazy = LazyOption.create(() => Option(1));

console.log(lazy instanceof LazyOption); // true
console.log(lazy instanceof Option);     // true

Option.fromReturn() method:

Signature:

Option.fromReturn(func, ...args);

Allows you to build on Option instance out of a function and a set of arguments to be passed to it:

let opt = Option.fromReturn((val1, val2) => { val1 * val2 }, 2, 20);

console.log(opt.get());     // 40

Option.ensure() method (v1.2.0):

Signature:

Option.ensure(val);

It will ensure, that any value given to it is an Option. If not - it will be wrapped into one:

let valueOne = "val",
    valueTwo = Option("other");

Option.ensure(valueOne);   // Some {}
Option.ensure(valueTwo);   // Some {}

LazyOption (v1.5.0)

const lazy = LazyOption.create((foo, bar) => Option(foo + bar), "Foo", "Bar");

lazy.map(v => v.toUpperCase())
    .filter(v => v.length > 0)
    .getOrElse("");             // "FooBar"

Examples

You can build functions that have a determined return type:

const {Some, None} = require("option-monad");

function someFunc(criteria) {
    let ret = someApi.getObject();

    if (ret === criteria) {
        return Some.create(ret); // You can also use "new Some(ret)" as well
    }

    // None is a singleton
    return None.create();
}

You can be completely sure that such function will always return Option type value.

Getting the value out of an Option:

let val = someFunc(true).get();

Will throw an Error if the return value is None.

Falling back to a default value:

let val = someFunc(true).getOrElse("fallback");

/* or ... */

let val = someFunc(true).getOrCall(() => { {foo: "fallback"} });

You can try different alternate options:

return someFunc(true)
    .orElse(someOtherApi().getObject())
    .orElse(someCrappyApi().getDefault());

You can utilize 'LazyOption' for delayed computation as a backup variant

return someFunc(true)
    .orElse(LazyOption.create(() => someOtherApi().getObject());

Development

You can make use of a few Gulp tasks out there:

  • gulp jshint runs JSHint
  • gulp test runs Mocha/Chai based tests
  • gulp default task, runs both tests and linting
  • gulp watch watches the changes on files, runts tests and JSHint on change