tiinvo
Version:
A library of types and utilities for your TypeScript and JavaScript projects
343 lines (342 loc) • 6.72 kB
JavaScript
//#region guards
/**
* Checks (at compile and runtime) if a given parameter `x` is a `number`
*
* @example
*
* ```ts
* import { Num } from 'tiinvo'
*
* const or0 = (x: unknown): t => Num.guard(x) ? x : 0;
*
* or0(10) // 10
* or0(20) // 20
* or0(-1) // -1
* or0(4e12) // 4e12
* or0('hello world') // 0
* or0(true) // 0
* or0(false) // 0
* or0({}) // 0
* ```
*
* @param x the value to check
* @group Guardables
* @since 4.0.0
*/
export const guard = (x) => typeof (x) === 'number';
export function cmp(a, b) {
const _cmp = (x, y) => x > y ? 1 : x < y ? -1 : 0;
if (guard(a) && guard(b)) {
return _cmp(a, b);
}
return (b) => _cmp(b, a);
}
;
export function eq(a, b) {
return guard(a) && guard(b) ? a === b : (c) => eq(a, c);
}
;
export function gt(a, b) {
if (guard(b)) {
return a > b;
}
return (b) => b > a;
}
export function lt(a, b) {
if (guard(b)) {
return a < b;
}
return (b) => b < a;
}
export function gte(a, b) {
if (guard(b)) {
return a >= b;
}
return (c) => c >= a;
}
export function lte(a, b) {
if (guard(b)) {
return a <= b;
}
return (b) => b <= a;
}
export function ne(a, b) {
if (guard(b)) {
return a !== b;
}
return (b) => b !== a;
}
//#endregion
//#region mappables
/**
* Maps a number `a` to a value `Result.t<b>` if a is `number`, otherwise returns `Err`.
*
* @example
*
* ```ts
* import { Num } from 'tiinvo';
*
* const toHex = Num.map(x => '0x' + x.toString(16))
*
* toHex(10) // 0xa
* toHex("a") // Error("a is not a number")
* ```
*
* @group Mappables
* @since 4.0.0
*/
export const map = (m) => (a) => guard(a) ? m(a) : new Error("a is not a number");
/**
* Maps a number `a` to a value `Result.t<b>` if a is `number`, otherwise returns `b`.
*
* @example
*
* ```ts
* import { Num } from 'tiinvo';
*
* const toHex = Num.mapOr(x => '0x' + x.toString(16), "0x0")
*
* toHex(10) // 0xa
* toHex("a") // 0x0
* ```
*
* @group Mappables
* @since 4.0.0
*/
export const mapOr = (m, b) => (a) => guard(a) ? m(a) : b;
//#endregion
//#region predicates
/**
* Returns true if a number `x` is even.
*
* @example
*
* ```ts
* import { Num } from 'tiinvo';
*
* Num.isEven(10) // true
* Num.isEven(91) // false
* ```
*
* @group Predicates
* @since 4.0.0
*/
export const isEven = x => x % 2 === 0;
/**
* Returns true if a number `x` is odd.
*
* @example
*
* ```ts
* import { Num } from 'tiinvo';
*
* Num.isOdd(10) // false
* Num.isOdd(91) // true
* ```
*
* @group Predicates
* @since 4.0.0
*/
export const isOdd = x => x % 2 !== 0;
/**
* Returns true if a number `x` is positive.
*
* @example
*
* ```ts
* import { Num } from 'tiinvo';
*
* Num.isNegative(-1) // true
* Num.isNegative(10) // false
* ```
*
* @group Predicates
* @since 4.0.0
*/
export const isNegative = x => x < 0;
/**
* Returns true if a number `x` is positive.
*
* @example
*
* ```ts
* import { Num } from 'tiinvo';
*
* Num.isPositive(-1) // false
* Num.isPositive(10) // true
* ```
*
* @group Predicates
* @since 4.0.0
*/
export const isPositive = x => x >= 0;
export function toExponential(a, b) {
if (guard(b)) {
return a.toExponential(b);
}
return (b) => b.toExponential(a);
}
export function toFixed(a, b) {
if (guard(b)) {
return a.toFixed(b);
}
return (b) => b.toFixed(a);
}
export function toPrecision(a, b) {
if (guard(b)) {
return a.toPrecision(b);
}
return (b) => b.toPrecision(a);
}
export function add(a, b) {
if (guard(b)) {
return a + b;
}
return (c) => c + a;
}
export function div(a, b) {
if (guard(b)) {
return a / b;
}
return (c) => c / a;
}
export function mod(a, b) {
if (guard(b)) {
return a % b;
}
return (c) => c % a;
}
export function mul(a, b) {
if (guard(b)) {
return a * b;
}
return (c) => c * a;
}
export function pow(a, b) {
if (guard(b)) {
return a ** b;
}
return (c) => c ** a;
}
export function root(a, b) {
if (guard(b)) {
return a ** (1 / b);
}
return (c) => c ** (1 / a);
}
export function sub(a, b) {
if (guard(b)) {
return a - b;
}
return (c) => c - a;
}
export function asc(a, b) {
if (guard(b)) {
return cmp(a, b);
}
return (c) => cmp(c, a);
}
export function desc(a, b) {
if (guard(b)) {
return cmp(b, a);
}
return (c) => cmp(a, c);
}
//#endregion
//#region serializables
/**
* Returns a number in binary notation.
*
* If the passed argument at runtime is not a number, an Error will be returned.
*
* @example
*
* ```ts
* import { Num } from 'tiinvo';
*
* Num.toBin(10) // "0b1010"
* ```
*
* @param a the number to convert to binary
* @returns the binary string
* @group Serializables
* @since 4.0.0
*/
export const toBin = map(x => '0b' + x.toString(2));
/**
* Returns a number in hexadecimal notation
*
* If the passed argument at runtime is not a number, an Error will be returned.
*
* @example
*
* ```ts
* import { Num } from 'tiinvo';
*
* Num.toHex(10) // "0xa"
* ```
*
* @param a the number to convert to hexadecimal
* @returns the hexadecimal string
* @group Serializables
* @since 4.0.0
*/
export const toHex = map(x => '0x' + x.toString(16));
/**
* Returns a number in octal notation
*
* If the passed argument at runtime is not a number, an Error will be returned.
*
* @example
*
* ```ts
* import { Num } from 'tiinvo';
*
* Num.toOct(10) // "0o12"
* ```
*
* @param a the number to convert to octal
* @returns the octal string
* @group Serializables
* @since 4.0.0
*/
export const toOct = map(x => '0o' + x.toString(8));
/**
* Returns a number in json notation.
*
* If the passed argument at runtime is not a number, an Error will be returned.
*
* @example
*
* ```ts
* import { Num } from 'tiinvo';
*
* Num.toJSON(10) // "10"
* ```
*
* @param a the number to convert to json value
* @returns the string
* @group Serializables
* @since 4.0.0
*/
export const toJSON = map(JSON.stringify);
/**
* Returns a stringified number.
*
* If the passed argument at runtime is not a number, an Error will be returned.
*
* @example
*
* ```ts
* import { Num } from 'tiinvo';
*
* Num.toString(10) // "10"
* ```
*
* @param a the number to convert to string
* @returns the string
* @group Serializables
* @since 4.0.0
*/
export const toString = map(String);
//#endregion