Either monad
npm install @sweet-monads/eitherEither Monad, The Either monad represents values with two possibilities: a value of type Either a b is either Left a or Right b.
> sweet-monads — easy-to-use monads implementation with static types definition and separated packages.
- No dependencies, one small file
- Easily auditable TypeScript/JS code
- Check out all libraries:
either,
iterator,
interfaces,
maybe
> npm install @sweet-monads/either
``typescript
import { Either, right } from "@sweet-monads/either";
class UserNotFoundError extends Error {
name: "UserNotFoundError";
}
type User = { email: string; password: string };
function getUser(id: number): Either
return right({ email: "test@gmail.com", password: "test" });
}
// Either
const user = getUser(1).map(({ email }) => email);
`
- chain
- merge
- mergeInOne
- mergeInMany
- left
- right
- from
- fromTry
- fromPromise
- isEither
- Either#isLeft
- Either#isRight
- Either#or
- Either#join
- Either#map
- Either#mapRight
- Either#mapLeft
- Either#asyncMap
- Either#apply
- Either#asyncApply
- Either#chain
- Either#asyncChain
- Either#fold
- Helpers
#### chain
`typescript`
function chain
- fn: (v: R) => Promise - function which should be applied asynchronously to Either valueEither
- Returns function with argument and promised Either with new error or mapped by fn value (could be used inside Promise#then function).
Example:
`typescript
const getValue = async () => right(1);
// Either
const result = await getValue()
.then(Either.chain(async v => right(v * 2)))
.then(Either.chain(async v => left(new TypeError("Unexpected"))));
`
#### merge
Alias for mergeInOne
`typescript`
function merge
function merge
function merge
values: [Either
): Either
// ... until 10 elements
- values: Array - Array of Either values which will be merged into Either of ArrayEither
- Returns which will contain Right if all of array elements was Right otherwise Left.
Example:
`typescript
const v1 = right
const v2 = right
const v3 = left
merge([v1, v2]); // Either
merge([v1, v2, v3]); // Either
`
#### mergeInOne
`typescript`
function merge
function merge
function merge
values: [Either
): Either
// ... until 10 elements
- values: Array - Array of Either values which will be merged into Either of ArrayEither
- Returns which will contain Right if all of array elements was Right otherwise Left.
Example:
`typescript
const v1 = right
const v2 = right
const v3 = left
merge([v1, v2]); // Either
merge([v1, v2, v3]); // Either
`
#### mergeInMany
`typescript`
function mergeInMany
function mergeInMany
function mergeInMany
values: [Either
): Either
// ... until 10 elements
- values: Array - Array of Either values which will be merged into Either of ArrayEither
- Returns which will contain Right if all of array elements was Right otherwise array of all caught Left values.
Example:
`typescript
const v1 = right
const v2 = right
const v3 = left
merge([v1, v2]); // Either
merge([v1, v2, v3]); // Either
`
#### left
`typescript`
function left
- Returns Either with Left state which contain value with L type.
Example:
`typescript`
const v1 = left(new Error()); // Either
const v2 = left
#### right
`typescript`
function right
- Returns Either with Right state which contain value with R type.
Example:
`typescript`
const v1 = right(2); // Either
const v2 = right
#### from
The same as right
Return only Right typed value.
`typescript`
function from
- Returns Either with Right state which contain value with R type.
Example:
`typescript`
from(2); // Either
#### fromTry
Returns Right with function result or Left if function execution throws an error.
`typescript`
function fromTry
`typescript`
fromTry(() => 2); // Either
fromTry(() => {
throw new Error("test");
}); // Either
#### fromPromise
Returns Right with the promise value if the provided promise fulfilled or Left with the error value if the provided promise rejected.
`typescript`
function fromPromise
`typescript`
fromPromise(Promise.resolve(2)); // Either
fromPromise(Promise.reject(new Error("test"))); // Either
#### isEither
`typescript`
function isEither
- Returns boolean if given value is instance of Either constructor.
Example:
`typescript`
const value: unknown = 2;
if (isEither(value)) {
// ... value is Either
}
#### Either#isLeft
`typescript`
function isLeft(): boolean;
- Returns true if state of Either is Left otherwise false
Example:
`typescript
const v1 = right(2);
const v2 = left(2);
v1.isLeft(); // false
v2.isLeft(); // true
`
#### Either#isRight
`typescript`
function isRight(): boolean;
- Returns true if state of Either is Right otherwise false
Example:
`typescript
const v1 = right(2);
const v2 = left(2);
v1.isRight(); // true
v2.isRight(); // false
`
#### Either#or
`typescript`
function or
- Returns Either. If state of this is Right then this will be returned otherwise x argument will be returned
Example:
`typescript
const v1 = right
const v2 = left
const v3 = left
const v4 = right
v1.or(v2); // v1 will be returned
v2.or(v1); // v1 will be returned
v2.or(v3); // v3 will be returned
v1.or(v4); // v1 will be returned
v2.or(v3).or(v1); // v1 will be returned
v2.or(v1).or(v3); // v1 will be returned
v1.or(v2).or(v3); // v1 will be returned
`
#### Either#join
`typescript`
function join
- this: Either - Either instance which contains other Either instance as Right value.Either
- Returns unwrapped - if current Either has Right state and inner Either has Right state then returns inner Either Right, if inner Either has Left state then return inner Either Left otherwise outer Either Left.
Example:
`typescript
const v1 = right(right(2));
const v2 = right(left(new Error()));
const v3 = left
v1.join(); // Either.Right with value 2
v2.join(); // Either.Left with value new Error
v3.join(); // Either.Left with value new TypeError
`
#### Either#map
`typescript`
function map
- Returns mapped by fn function value wrapped by Either if Either is Right otherwise Left with L value
Example:
`typescript
const v1 = right
const v2 = left
const newVal1 = v1.map(a => a.toString()); // Either
const newVal2 = v2.map(a => a.toString()); // Either
`
#### Either#mapRight
`typescript`
function mapRight
The same as Either#map
- Returns mapped by fn function value wrapped by Either if Either is Right otherwise Left with L value
Example:
`typescript
const v1 = right
const v2 = left
const newVal1 = v1.map(a => a.toString()); // Either
const newVal2 = v2.map(a => a.toString()); // Either
`
#### Either#mapLeft
`typescript`
function mapLeft
- Returns mapped by fn function value wrapped by Either if Either is Left otherwise Right with R value
Example:
`typescript
const v1 = right
const v2 = left
const newVal1 = v1.mapLeft(a => a.toString()); // Either
const newVal2 = v2.mapLeft(a => a.toString()); // Either
`
##### Either#asyncMap
`typescript`
function asyncMap
- Returns Promise with mapped by fn function value wrapped by Either if Either is Right otherwise Left with value L
Example:
`typescript
const v1 = right
const v2 = left
// Promise
const newVal1 = v1.asyncMap(a => Promise.resolve(a.toString()));
// Promise
const newVal2 = v2.asyncMap(a => Promise.resolve(a.toString()));
`
##### Either#apply
`typescript`
function apply(this: Either
function apply(this: Either
- this | fn - function wrapped by Either, which should be applied to value argarg | this
- - value which should be applied to fnfn
- Returns mapped by function value wrapped by Either if Either is Right otherwise Left with L value
Example:
`typescript
const v1 = right
const v2 = left
const fn1 = right
const fn2 = left
const newVal1 = fn1.apply(v1); // Either
const newVal2 = fn1.apply(v2); // Either
const newVal3 = fn2.apply(v1); // Either
const newVal4 = fn2.apply(v2); // Either
`
##### Either#asyncApply
Async variant of Either#apply
`typescript`
function asyncApply(this: Either
function asyncApply(this: Either
function asyncApply(
this: Either
argOrFn: Either
): Promise
- this | fn - function wrapped by Either, which should be applied to value argarg | this
- - value which should be applied to fnPromise
- Returns with mapped by fn function value wrapped by Either if Either is Right otherwise Left with L value
Example:
`typescript
const v1 = right
const v2 = left
const fn1 = right
const fn2 = left
const newVal1 = fn1.apply(v1); // Promise
const newVal2 = fn1.apply(v2); // Promise
const newVal3 = fn2.apply(v1); // Promise
const newVal4 = fn2.apply(v2); // Promise
`
#### Either#chain
`typescript`
function chain
- Returns mapped by fn function value wrapped by Either if Either is Right and returned by fn value is Right too otherwise Left
Example:
`typescript
const v1 = right
const v2 = left
// Either
const newVal1 = v1.chain(a => right
// Either
const newVal2 = v1.chain(a => left
// Either
const newVal3 = v2.chain(a => right
// Either
const newVal4 = v2.chain(a => left
`
##### Either#asyncChain
`typescript`
function chain
- Returns Promise with mapped by fn function value wrapped by Either if Either is Right and returned by fn value is Right too otherwise Left
Example:
`typescript
const v1 = right
const v2 = left
// Promise
const newVal1 = v1.asyncChain(a => right
// Promise
const newVal2 = v1.asyncChain(a => left
// Promise
const newVal3 = v2.asyncChain(a => right
// Promise
const newVal4 = v2.chain(a => left
`
##### Either#fold
`typescript`
function fold
- Returns values mapped by mapRight if Either is Right, otherwise value mapped by mapLeft
Example:
`typescript
const v1 = right
const v2 = left
// 4
const newVal1 = v1.fold(() => 'fail', value => value * 2);
// "fail"
const newVal2 = v2.fold(() => 'fail', value => value * 2);
`
#### Helpers
`typescript`
// Value from Either instance
const { value } = right
const { value } = right(2); // number
const { value } = left
const { value } = left(new Error()); // Error
`typescript
right(2).unwrap(); // number
left(new TypeError()).unwrap(); // throws error
right(2).unwrap(); // number
left(new TypeError()).unwrap(x => x); // throws TypeError provied in arguments
left(2).unwrapOr(3) // returns 3
rigth(2).unwrapOr(3) // returns 2
left(2).unwrapOrElse(num => num * 2) // returns 4
right(2).unwrapOrElse(num => num * 2) // returns 2
``
MIT (c) Artem Kobzar see LICENSE file.