/**
* @module maybe
*/
import Just, {isJust, just} from './Just';
import Nothing, {isNothing, nothing} from './Nothing';
import {isset, curry, id, trampoline} from 'fjl';
import {getMonadUnWrapper} from '../monad/Monad';
export {Just, isJust, isNothing, Nothing, just, nothing};
const
/**
* @private
*/
[justUnWrapper, justUnWrapperTailCallName] = getMonadUnWrapper(Just)
;
export const
/**
* The maybe function takes a `replacement` value, a function (unary operation), and a Maybe value. If the Maybe value is `Nothing`, the function returns the `replacement` value. Otherwise, it applies the function to the value contained by the `Just` and returns the result.
* @function module:maybe.maybe
* @param replacement {*}
* @param fn {Function} - Unary operation.
* @param maybeInst {(Nothing|Just|*)} - Maybe instance or non-maybe value.
* @returns {*}
*/
maybe = curry((replacement, fn, maybeInst) => {
const subject = isset(maybeInst) && isMaybe(maybeInst) ? maybeInst.map(id) : nothing();
return isNothing(subject) ? replacement : subject.map(fn).join();
}),
/**
* Unwraps just (recursively).
* @function module:maybe.unWrapJust
* @param x {*} - Expected `Just`.
* @returns {*}
*/
unWrapJust = trampoline(justUnWrapper, justUnWrapperTailCallName),
/**
* Unwraps maybe (recursively).
* @function module:maybe.unWrapMaybe
* @param x {*} - Expected `Maybe`.
* @returns {*}
*/
unWrapMaybe = x => isNothing(x) ? nothing() : unWrapJust(x),
/**
* Equality operator for maybes.
* @function module:maybe.maybeEqual
* @param a {*} - Maybe 1.
* @param b {*} - Maybe 2.
* @returns {boolean}
*/
maybeEqual = curry((a, b) => unWrapMaybe(a) === unWrapMaybe(b)),
/**
* Checks for maybe.
* @function module:maybe.isMaybe
* @param x {*}.
* @returns {boolean}
*/
isMaybe = x => isNothing(x) || isJust(x),
/**
* Creates maybe from value.
* @function module:maybe.toMaybe
* @param x {*}
* @returns {Maybe} - `Just` or `Nothing` based on value.
*/
toMaybe = x => {
if (!isset(x)) {
return nothing();
}
return isMaybe(x) ? x : just(x);
}
;