Skip to content

thames-technology/monads

Repository files navigation

Monads Logo

If you use this repo, star it ✨


Option, Result, and Either types for JavaScript

🦀 Inspired by Rust

Zero dependenciesLightweightFunctional


Install

npm install @thames/monads

Getting started

The Option<T> type

Option represents an optional value: every Option is either Some and contains a value, or None, and does not.

Note

Full documentation here: Option

import { Option, Some, None } from '@thames/monads';

const divide = (numerator: number, denominator: number): Option<number> => {
  if (denominator === 0) {
    return None;
  } else {
    return Some(numerator / denominator);
  }
};

// The return value of the function is an option
const result = divide(2.0, 3.0);

// Pattern match to retrieve the value
const message = result.match({
  some: (res) => `Result: ${res}`,
  none: 'Cannot divide by 0',
});

console.log(message); // "Result: 0.6666666666666666"

The Result<T, E> type

Result represents a value that is either a success (Ok) or a failure (Err).

Note

Full documentation here: Result

import { Result, Ok, Err } from '@thames/monads';

const getIndex = (values: string[], value: string): Result<number, string> => {
  const index = values.indexOf(value);

  switch (index) {
    case -1:
      return Err('Value not found');
    default:
      return Ok(index);
  }
};

const values = ['a', 'b', 'c'];

getIndex(values, 'b'); // Ok(1)
getIndex(values, 'z'); // Err("Value not found")

The Either<L, R> type

Either represents a value that is either Left or Right. It is a powerful way to handle operations that can result in two distinctly different types of outcomes.

Note

Full documentation here: Either

import { Either, Left, Right } from '@thames/monads';

const divide = (numerator: number, denominator: number): Either<string, number> => {
  if (denominator === 0) {
    return Left('Cannot divide by 0');
  } else {
    return Right(numerator / denominator);
  }
};

const result = divide(2.0, 3.0);

const message = result.match({
  left: (err) => `Error: ${err}`,
  right: (res) => `Result: ${res}`,
});

console.log(message); // "Result: 0.6666666666666666"