import { Monad } from './Monad';
import { Either, left, right } from './Either';
/**
* just wraps a value in a Just
*/
export const just = (a: A): Maybe => new Just(a);;
/**
* nothing constructs nothing
*/
export const nothing = () => new Nothing();
/**
* fromAny constructs a Maybe from a value that may be null.
*/
export const fromAny = (a: A): Maybe => a == null ? nothing() : just(a);
/**
* fromArray checks an array to see if it's empty (or full of nulls)
* and returns a Maybe.
*/
export const fromArray = (a: A[]): Maybe =>
((a.length === 0) || (a.reduce((c, v) => (v == null) ? c + 1 : c, 0) === a.length)) ?
nothing() : just(a)
/**
* fromOBject uses Object.keys to turn see if an object has any own properties.
*/
export const fromObject = (o: A): Maybe =>
Object.keys(o).length === 0 ? nothing() : just(o);
/**
* fromString constructs nothing if the string is empty or just otherwise.
*/
export const fromString = (s: string): Maybe =>
(s === '') ? nothing() : just(s);
/**
* fromBoolean constructs nothing if b is false, just otherwise
*/
export const fromBoolean = (b: boolean): Maybe =>
(b === false) ? nothing() : just(b);
/**
* fromNumber constructs nothing if n is 0 just otherwise.
*/
export const fromNumber = (n: number): Maybe =>
(n === 0) ? nothing() : just(n);
/**
* isString tests whether the value is a string or not.
*/
export const isString = (s: any): Maybe =>
(typeof s === 'string') ? just(s) : nothing();
/**
* isBoolean tests whether the value is a boolean or not.
*/
export const isBoolean = (b: any): Maybe =>
(typeof b === 'boolean') ? just(b) : nothing();
/**
* isTrue constructs nothing if b !== true
*/
export const isTrue = (b: any): Maybe =>
(b === true) ? just(b) : nothing();
/**
* isFalse constructs nothing if b !== false
*/
export const isFalse = (b: any): Maybe =>
(b === false) ? just(b) : nothing();
/**
* isNumber tests whether the value is number or not.
*/
export const isNumber = (n: any): Maybe =>
(typeof n === 'number') ? just(n) : nothing();
/**
* isObject tests whether the value is an object or not.
*/
export const isObject = (o: any): Maybe