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

monadness

v0.5.2

Published

TypeScript/JavaScript library of Maybe, Either and Tuple Monads.

Downloads

8

Readme

Build Status Coverage Status npm version

monadness-js

A TypeScript/JavaScript library that implements some basic "objects" of functional programming.

The advantages of using these classes:

  • Code that's easier to reason about.
  • Better error handling.
  • Avoid null and undefined issues.

Install

npm i -S monadness

Quick Examples

Example code for Maybe:

import { Maybe } from "monadness";

function getFileContents (filePath: string): Maybe<string> {
    /* Code to sync read file */
    return Maybe.fromNull(contents);
}

const contents = getFileContents("path/to/filename.json");

if (contents.isDefined()) {
    console.log("File contents:", contents.get());
} else {
    console.error("File error: File not loaded.");
}

console.log("File contents:", contents.getOrElseGet(""));

Example code for Either:

import { Either } from "monadness";

function getFileContents (filePath: string): Either<Error, string> {

    /* Code to sync read file */

    if (contents === undefined) {
        return Either.left<Error, string>(new Error(`File ${filePath} not found.`);
    } else {
        return Either.right<Error, string>(contents);
    }
}

const contents = getFileContents("path/to/filename.json");

if (contents.isRight()) {
    console.log("File contents:", contents.get());
} else {
    console.error("File error:", contents.getLeft());
}

contents.cata(
    content => console.log("File contents:", content),
    err => console.error("File error:", err),
);

Example code for Tuples:

import { Tuples } from "monadness";

const tuple = Tuples.from(1, "two", true);

const [a, b, c] = tuple;
console.log(a, b, c);
// 1, "two", true

const newTuple1 = tuple.map(a => a + a);
console.log(newTuple1._1, newTuple1._2, newTuple1._3);
// 2, "twotwo", 2

const newTuple2 = tuple.mbind(Tuples.from(
    a => Tuples.from(a + a),
    b => Tuples.from(b + "three"),
    c => Tuples.from(!! c),
));
console.log(newTuple2._1, newTuple2._2, newTuple2._3);
// 2, "twothree", false

Usage

TypeScript / ES6

import { Either, Maybe, Tuples } from "monadness";

NodeJS

const Monadness = require("monadness"),
      Either = Monadness.Either,
      Maybe = Monadness.Maybe,
      Tuples = Monadness.Tuples;

Browser

<script src="node_modules/dist/monadness.min.js"></script>
<script src="node_modules/dist/monadness.es6.min.js"></script>

Maybe

The Maybe class can be an instance with a defined value (Maybe.Just) or no value (Maybe.None).

This is a better alternative to throwing errors or returning undefined values. It lets the type-checker discover errors at compile time.

Static Methods

Maybe.just

Creates a Maybe.Just with the given value.

Maybe.just <T> (value: T): Maybe<T>

Maybe.none

Creates a Maybe.None.

Maybe.none <T> (): Maybe<T>

Maybe.nothing

Returns the Maybe.nothing singleton.

Maybe.nothing (): Maybe<void>

Maybe.fromNull

Creates a Maybe.Just with the given value or, if the value is null or undefined, a Maybe.None.

Maybe.fromNull <T> (value: T | undefined | null): Maybe<T>

Maybe.sequence

Turns an array of Maybes into a Maybe of arrays.

Maybe.sequence <T> (...maybes: Array<Maybe<T>>): Maybe<T[]>

Maybe.traverse

Maps an array into a Maybe of arrays.

Maybe.traverse <T, U> (f: (a: T) => Maybe<U>): (as: T[]) => Maybe<U[]>

Maybe.lift

Maybe.lift <T> (partialFunction: (...args: any[]) => T): (...args: any[]) => Maybe<T>

Instance Methods

isEmpty

Returns true if this is a Maybe.None.

isEmpty (): boolean

isDefined

Returns true if this is a Maybe.Right.

isDefined (): boolean

get

Returns the Just value or throws an error if None.

get (): T | never

getOrElse

Returns the Just value or the result of the given function.

getOrElse (value: () => T): T

getOrElseGet

Returns the Just value or the given value.

getOrElseGet (value: T): T

getOrThrow

Returns the Just value or throws the given error.

getOrThrow (err?: Error): T | never

orElse

Returns the Just value or the function result.

orElse (o: () => Maybe<T>): Maybe<T>

map

Applies the Maybe function to the value and return the result wrapped in a Maybe.

map <U> (f: (a: T) => U): Maybe<U>

fmap

Applies the function to the value and return the result.

fmap <U> (f: (a: T) => Maybe<U>): Maybe<U>

applies

applies <U, V> (f: (a: T) => (b: U) => Maybe<V>): (mb: Maybe<U>) => Maybe<V>

mbind

Applies the Maybe function to the value and return the result.

mbind <U> (f: Maybe<(a: T) => Maybe<U>>): Maybe<U>

flatten

Converts a Maybe of nested Maybes to a one-depth Maybe.

flatten <U> (): Maybe<U>

toEither

Converts the Maybe to an Either.

toEither (): Either.Right<Error, T>

toObject

Returns an object or null.

toObject (): { just: T | null; }

toJSON

Returns an object or null.

toJSON (): { just: T | null }

toString

Returns a string representation of the Maybe: '{ "just": T }'

toString (): string

equals

Tests the equality of two Maybes.

equals (other: Maybe<T>): boolean

Either

An Either can hold one of two values, a Left or Right value. Conventionly, a success is a right value and an error is a left value. (Right is right and left is wrong.)

This is a better alternative to throwing errors or returning undefined values. It lets the type-checker discover errors at compile time.

Static Methods

right

Returns an Either.Right with the given value.

Either.right <L, R> (right: R)

left

Returns an Either.Left with the given value.

Either.left <L, R> (left: L)

nothing

Returns the Either.nothing singleton.

Either.nothing (): Left<void, void>

sequence

Converts an array of Eithers into an Either of an array.

Either.sequence <L, R> (...eithers: Array<Either<L, R>>): Either<L, R[]>

traverse

Maps an array into an Either of an array.

Either.traverse <L, R, S> (f: (a: R) => Either<L, S>): (as: R[]) => Either<L, S[]>

lift

Either.lift <Error, T> (partialFunction: (...args: any[]) => T): (...args: any[]) => Either<Error, T>

Instance Methods

isLeft

Returns true if this is an Either.Left.

isLeft (): boolean

isRight

Returns true if this is an Either.Right.

isRight (): boolean

get

Returns the right value, or throws an error if Either.Left.

get (): R | never;

getRight

Returns the right value, or throws an error if Either.Left.

getRight (): R | never

getLeft

Returns the left value, or throws an error if Either.Right.

getLeft (): L | never

getOrElse

Returns the right value or the result of the given function.

getOrElse (f: () => R): R

getOrElseGet

Returns the right value or the given value.

getOrElseGet (right: R): R

getOrThrow

Returns the right value or throws the given error.

getOrThrow (err?: Error): R | never

orElse

Returns the right value or the result of the given function.

orElse (f: () => Either<L, R>)

map

Applies the function to the value and wraps the result in another Either.

map <S> (f: (a: R) => S): Either<L, S>

fmap

Applies the function to the value and returns the result.

fmap <S> (f: (a: R) => Either<L, S>): Either<L, S>

applies

applies <S, T> (f: ApplicativeFunc<R, S, T>): (mb: Either<L, S>) => Either<L, T>

###mbind

Basically maps the right value to the Either.Right function.

mbind <S> (f: Either<L, (f: R) => Either<L, S>>): Either<L, S>

bimap

Applies the applicable function to the value and produces an Either.

bimap <M, S> (lf: (l: L) => M, rf: (r: R) => S): Either<M, S>

cata

Applies the applicable function to the Either and produces a value.

cata <V> (lf: (l: L) => V, rf: (r: R) => V): V

flatten

Flattens an Either of nested Eithers to a one depth Either.

flatten <M, S> (): Either <M, S>

toMaybe

Converts this Either to a Maybe.

toMaybe (): Maybe<R>

toObject

Converts the instance to a basic object.

toObject (): { left?: L; right?: R }

toJSON

Allows the instance to be converted to JSON.

toJSON (): { left?: L; right?: R }

toString

Returns the Either as a string: '{"right": R}' or '{"left": L}'

toString (): string

equals

Tests the equality of the Eithers.

equals (other: Either<L, R>): boolean

Tuples

Monadness tuples are simply arrays with some extra methods.

Static Methods

Tuples.from

Tuples.from <T1, ...Tn> (_1: T1, ..._n: Tn): TupleN <T1, ...Tn> & [T1, ...Tn]

Instance Getters

Accesses the values of the tuple (not zero-based).

_1: T1;
_n: Tn;

Instance Methods

In addition to all of the regular array methods, the Tuple class has the following methods.

map

Applies the function to each value of the tuple.

map <U1, ...Un> (f: (a: T1 | ...Tn) => U1 | ...Un): Tuple9<U1, ...Un>

fmap

Applies the function to each value of the tuple.

fmap <U1, ...U9> (f: (a: T1 | ...Tn) => Tuple1<U1 | ...Un>): Tuple9<U1, ...Un>

applies

applies <U1, U2, ...Un, V1, ...Vn> (f: ApplicativeFunc<T1 | ...Tn, U1 | ...Un, V1 | ...Vn>): (mb: Tuple9<U1, ...Un>) => Tuple9<V1, ...Vn>

mbind

Applies each function to each value respectively.

mbind <U1, ...Un> (f: TupleN<TMF<T1, U1>, ...TMF<Tn, Un>>): TupleN<U1, ...Un>

toJSON

Converts the tuple to a JSON object.

toJSON (): { just: T | null }

equals

Tests the equality of two tuples.

equals (other: TupleN<T>): boolean

Example of Static Initializers and Usage:

import { Tuples } from "monadness";

const tuple0 = Tuples.from();
const tuple1 = Tuples.from("a");
const tuple2 = Tuples.from("a", 2);
const tuple3 = Tuples.from(123, "abc", true);
const tuple4 = Tuples.from(1, 2, 3, 4);
const tuple5 = Tuples.from(1, 2, 3, 4, 5);
const tuple6 = Tuples.from(1, 2, 3, 4, 5, 6);
const tuple7 = Tuples.from(1, 2, 3, 4, 5, 6, 7);
const tuple8 = Tuples.from(1, 2, 3, 4, 5, 6, 7, 8);
const tuple9 = Tuples.from(1, 2, 3, 4, 5, 6, 7, 8, 9);

console.log("First value:", tuple2._1, tuple[0]);
console.log("Second value:", tuple2._2, tuple[1]);

const [x, y] = tuple2; // Desctructuring

for (const i in tuple4) {
    console.log("Tuple4 values:", tuple4[i]);
}

for (const val of tuple5) {
    console.log("Tuple5 values:", val);
}

License

(The MIT License)

Copyright (c) 2017 Patrick Martin

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.