Either

data. Either

new Either()

The Either union type and its subtypes Right and Left. Usually they are used whenever an operation might result in an error. Typically the error value is placed in a Left while the result is placed in a Right (because canonically "right" means "correct")

Version:
  • 3.0.0
Source:
Example
const {Either} = require('futils').data;
const {Left, Right} = Either;

Either.Right(1); // -> Right(1)
Right(1);        // -> Right(1)

Either.Left(0);  // -> Left(0)
Left(0);         // -> Left(0)

Either.Right(1).value; // -> 1
Either.Left(0).value;  // -> 0

Extends

Methods

(static) empty() → {Left}

Monoid implementation for Either. Returns a Either.Left with a value of null

Source:
Returns:
Type:
Left

A Either.Left

Example
const {Either} = require('futils').data;

Either.empty(); // -> Left(null)

(static) from(a) → {Left|Right}

Lifts a value into a Either. Similiar to Either.of, but if the value is either null, undefined or some error it returns a Either.Left

Source:
Parameters:
Name Type Description
a any

The value to lift

Returns:
Type:
Left | Right

Either.Right for all values which are not null, undefined or some error

Example
const {Either} = require('futils').data;

Either.from(1);                   // -> Right(1)
Either.from(null);                // -> Left(null)
Either.from(new Error('failed')); // -> Left(Error)

(static) fromList(a) → {Left|Right}

A natural transformation from a List into a Either. Please note that this transformation looses data, because only the first element of the list is taken. If the first element is null, undefined or some error, a Either.Left is returned

Source:
Parameters:
Name Type Description
a List

The List to transform

Returns:
Type:
Left | Right

Either.Right if the first element is not null, undefined or some error

Example
const {Either, List} = require('futils').data;

const ls = List.of(2).cons(1);
const ks = List.Nil();

Either.fromList(ls); // -> Right(1)
Either.fromList(ks); // -> Left(null)

(static) fromMaybe(a) → {Left|Right}

A natural transformation from a Maybe.Some or Maybe.None into a Either

Source:
Parameters:
Name Type Description
a Some | None

The Maybe to transform

Returns:
Type:
Left | Right

Either.Right if given a Maybe.Some, Either.Left otherwise

Example
const {Either, Maybe} = require('futils').data;

const some = Maybe.Some(1);
const none = Maybe.None();

Either.fromMaybe(some); // -> Right(1)
Either.fromMaybe(none); // -> Left(null)

(static) of(a) → {Right}

Lifts a value into a Either.Right

Source:
Parameters:
Name Type Description
a any

The value to lift

Returns:
Type:
Right

The value wrapped in a Either.Right

Example
const {Either} = require('futils').data;

Either.of(1); // -> Right(1)

(static) try(a) → {function}

A natural transformation from a State, a IO or a function into a Either. Returns a function that awaits a argument to run the computation and which returns a Either.Right if the computation succeeds or a Either.Left if it fails

Source:
Parameters:
Name Type Description
a IO | State | function

The computation

Returns:
Type:
function

A function which takes arguments to run the computation

Example
const {Either, IO} = require('futils').data;

const ioEnv = IO((key) => process[key]);
const even = (n) => n % 2 === 0 ? n : null;

Either.try(ioEnv)('arch'); // -> Right(<architecture>)
Either.try(even)(2);       // -> Right(2)
Either.try(ioEnv)('foo');  // -> Left(null)
Either.try(even)(1);       // -> Left(null)
Either.try(null)();        // -> Left(Error)

alt(a) → {Left|Right}

Alt implementation, allows to swap a Either.Left

Source:
Parameters:
Name Type Description
a Left | Right

The alternative Either

Returns:
Type:
Left | Right

Choosen alternative

Example
const {Either} = require('futils').data;

const r = Either.Right(1);
const l = Either.Left(1);

r.alt(Either.Right(2)); // -> Right(1)
r.alt(Either.Left(0));  // -> Right(1)
l.alt(Either.Right(2)); // -> Right(2)
l.alt(Either.Left(0));  // -> Left(0)

ap(a) → {Left|Right}

Applies a function in a Either.Right to a value in another Either.Right

Source:
Parameters:
Name Type Description
a Left | Right

The Either that holds the value

Returns:
Type:
Left | Right

Either which contains the result of applying the function

Example
const {Either} = require('futils').data;

const r = Either.Right(1);
const l = Either.Left('ignored');

const mInc = Either.Right((n) => n + 1);

mInc.ap(r); // -> Right(2)
mInc.ap(l); // -> Left('ignored')

biMap(f, g) → {Left|Right}

Bifunctor interface, maps either of two functions over the value inside a Either

Source:
Parameters:
Name Type Description
f function

Function to map if the structure is a Either.Left

g function

Function to map if the structure is a Either.Right

Returns:
Type:
Left | Right

Either with the result of applying either of the functions

Example
const {Either} = require('futils').data;

const r = Either.Right('a');
const l = Either.Left(null);

const upperCase = (v) => v.toUpperCase();
const defaultChar = () => 'X';

r.biMap(defaultChar, upperCase); // -> Right('A')
l.biMap(defaultChar, upperCase); // -> Right('X')

concat(a) → {Right|Left}

Concatenates a Either.Right with another. concatenation with Either.Left will result in Either.Left. Please note, that the inner values have to be part of a Semigroup as well for concatenation to succeed

Source:
Parameters:
Name Type Description
a Right | Left

The Either instance to concatenate with

Returns:
Type:
Right | Left

A new Either

Example
const {Either} = require('futils').data;

const r = Either.Right('r');
const l = Either.Left('l');

r.concat(Either.Right('b')); // -> Right('rb')
r.concat(Either.Left('b'));  // -> Left('b')
l.concat(Either.Right('b')); // -> Left('l')
l.concat(Either.Left('b'));  // -> Left('l')

extend(f) → {Left|Right}

If given a function that takes a Either and returns a value, returns a Either

Source:
Parameters:
Name Type Description
f function

A function taking a Either.Right or Either.Left

Returns:
Type:
Left | Right

A new Either

Example
const {Either} = require('futils').data;

const r = Either.Right('a right');
const l = Either.Left('a left');

r.extend(({value}) => /right/.test(value)); // -> Right(true)
l.extend(({value}) => /right/.test(value)); // -> Left(false)

extract() → {any}

Extracts the value from a Either.Right or Either.Left

Source:
Returns:
Type:
any

The current value

Example
const {Either} = require('futils').data;

Either.Right('a right').extract(); // -> 'a right'
Either.Left('a left').extract();   // -> 'a left'

flat() → {Left|Right}

Flattens a nested Either.Right one level

Source:
Returns:
Type:
Left | Right

A flat Either.Right

Example
const {Either} = require('futils').data;

const r = Either.Right(Either.Right('r'));
const l = Either.Left('l');

r.flat(); // -> Right('r')
l.flat(); // -> Left('l')

flatMap(f) → {Left|Right}

Maps a Either returning function over a Either.Right and flattens the result

Source:
Parameters:
Name Type Description
f function

A Either returning function to map

Returns:
Type:
Left | Right

A new Either

Example
const {Either} = require('futils').data;

const r1 = Either.Right(2);
const r2 = Either.Right(1);
const l = Either.Left('ignored');

const even = (n) => n % 2 === 0 ? Either.Right(`even ${n}`) : Either.Left('not even')

r1.map(even); // -> Right('even 2')
r2.map(even); // -> Left('not even')
l.map(even);  // -> Left('ignored')

isRight() → {Boolean}

Test if the instance is a Either.Right or a Either.Left

Source:
Returns:
Type:
Boolean

True for Either.Right

Example
const {Either} = require('futils').data;

const r = Either.Right(1);
const l = Either.Left(null);

r.isRight(); // -> true
l.isRight(); // -> false

map(f) → {Left|Right}

Maps a function over the inner value and wraps the result in a new Either. Does not map the function over a Either.Left

Source:
Parameters:
Name Type Description
f function

The function to map

Returns:
Type:
Left | Right

A new Either.Right or the instance for Maybe.Left

Example
const {Either} = require('futils').data;

const r = Either.Right('r');
const l = Either.Left('l');

const upperCase = (v) => v.toUpperCase();

r.map(upperCase); // -> Right('R')
l.map(upperCase); // -> Left('l')

mapLeft(f) → {Left|Right}

Maps a function over the value in a Left

Source:
Parameters:
Name Type Description
f function

The function to map

Returns:
Type:
Left | Right

A new Either

Example
const {Either} = require('futils').data;

const l = Either.Left(null);

const noValueErr = a => a === null || a === undefined ? 'NoValue' : a;
                                                    
l.mapLeft(noValueErr);  // -> Left('NoValue')

reduce(f, x) → {any}

Works much like the Array.reduce method. If given a function and an initial value, returns the initial value for a Either.Left and calls the function with the initial value and the current value of a Either.Right

Source:
Parameters:
Name Type Description
f function

The function to reduce with

x any

The seed value to reduce into

Returns:
Type:
any

Either the seed value or whatever the reducer function returned

Example
const {Either} = require('futils').data;

const r = Either.Right('world');
const l = Either.Left(null);

const reducer = (a, b) => a.concat(b);

r.reduce(reducer, 'hello'); // -> 'helloworld'
l.reduce(reducer, 'hello'); // -> 'hello'

sequence(A) → {Applicative|Array}

Sequences a Either into another applicative Type

Source:
Parameters:
Name Type Description
A Applicative | Array

A constructor with of and ap methods

Returns:
Type:
Applicative | Array

A Either wrapped in the applicative

Example
const {Either} = require('futils').data;

const r = Either.Right([1]);
const l = Either.Left([0]);

r.sequence(Array); // -> [Right(1)]
l.sequence(Array); // -> [Left(0)]

swap() → {Left|Right}

Swaps the disjunction of a Either, meaning a Either.Left becomes a Either.Right and a Either.Right becomes a Either.Left

Source:
Returns:
Type:
Left | Right

A new Either

Example
const {Either} = require('futils').data;

const r = Either.Right(1);
const l = Either.Left(1);

r.swap(); // -> Left(1);
l.swap(); // -> Right(1)

traverse(f, A) → {Applicative|Array}

Takes a function with signature (Applicable f) => a -> f a and an Applicative constructor and traverses the Either into the applicative

Source:
Parameters:
Name Type Description
f function

Function to traverse with

A Applicative | Array

A constructor with of and ap methods

Returns:
Type:
Applicative | Array

A Either wrapped in the applicative

Example
const {Either} = require('futils').data;

const r = Either.Right(1);
const l = Either.Left(0);

const fn = (n) => [n];

r.traverse(fn, Array); // -> [Right(1)]
l.traverse(fn, Array); // -> [Left(0)]