feat: math docs

This commit is contained in:
2026-06-27 20:46:09 +02:00
parent 408806d17b
commit a57b11b451
26 changed files with 390 additions and 8931 deletions
+390 -9
View File
@@ -48,82 +48,463 @@ export interface Math extends Mixin.HKT {
new: (t: HKT.T<this>) => Input<typeof t> extends infer T
? T extends number
? {
add: (other: number) => Return<number, typeof t>;
subtract: (
/**
* `x + y`
* @param other The second term of the addition (`y`)
* @from {@link Math `Math`}
* @example
* ```ts
* const v = $(12).add(8).value;
* expect(v).toBe(20);
* ```
*/
add: (
/** Term to add */
other: number,
) => Return<number, typeof t>;
/**
* `x - y`
* @param other The second term of the subtraction (`y`)
* @from {@link Math `Math`}
* @example
* ```ts
* const v = $(12).subtract(8).value;
* expect(v).toBe(4);
* ```
*/
subtract: (
/** Term to subtract by */
other: number,
) => Return<number, typeof t>;
/**
* `x * y`
* @param factor Factor term of the multiplication (`y`)
* @from {@link Math `Math`}
* @example
* ```ts
* const v = $(12).multiply(8).value;
* expect(v).toBe(96)
* ```
*/
multiply: (
/** Factor to multiply by */
factor: number,
) => Return<number, typeof t>;
/**
* `x ** y`
* @param exponent Exponent term of the power (`y`)
* @from {@link Math `Math`}
* @example
* ```ts
* const v = $(12).pow(2).value;
* expect(v).toBe(144);
* ```
*/
pow: (
/** Exponent to raise to */
exponent: number,
) => Return<number, typeof t>;
/**
* `Math.sqrt(x)`
* @from {@link Math `Math`}
* @example
* ```ts
* const v = $(144).sqrt().value;
* expect(v).toBe(12);
* ```
*/
sqrt: () => Return<number, typeof t>;
/**
* `x / y`
* @param divisor Divisor term of the division (`y`)
* @from {@link Math `Math`}
* @example
* ```ts
* const v = $(12).divide(8).value;
* expect(v).toBe(1.5);
* ```
*/
divide: (
/** Divisor to divide by */
divisor: number,
) => Return<number, typeof t>;
/**
* `x % y`
* @param divisor Divisor term of the remainder operation (`y`)
* @from {@link Math `Math`}
* @example
* ```ts
* const v = $(12).mod(8).value;
* expect(v).toBe(4);
* ```
*/
mod: (
/** Divisor to divide by */
divisor: number,
) => Return<number, typeof t>;
log: (base?: number) => Return<number, typeof t>;
/**
* `ln(x)`, `log(x, base)`, or alternatively `Math.log(x) / Math.log(base)`
* @param base Base of the logarithm (`base`). Defaults to `Math.E` for a natural logarithm function
* @from {@link Math `Math`}
* @example
* ```ts
* const a = $(Math.E).log().value;
* expect(a).toBe(1);
*
* const b = $(125).log(5).value;
* expect(b).toBeCloseTo(3);
* ```
*/
log: (
/** The base of the logarithm */
base?: number,
) => Return<number, typeof t>;
/**
* Loosely compare value to the specified other value,
* accounting for floating-point inaccuracies. Comparision
* is performed within some degree of error.
* @param other Value to compare against
* @param delta The degree of acceptable error (defaults to `Number.EPSILON`)
* @from {@link Math `Math`}
* @example
* ```ts
* const result = 0.1 + 0.2;
* const target = 0.3;
*
* const a = $(result).comparesTo(target).value;
* expect(a).toBe(true);
*
* const b = $(result).comparesTo(1, 1).value;
* expect(b).toBe(true);
*
* const c = $(result).comparesTo(0).value;
* expect(c).toBe(false);
* ```
*/
comparesTo: (
/** Value to compare against */
other: number,
/** Degree of acceptable error */
delta?: number,
) => Return<boolean, typeof t>;
/**
* `Math.floor(x)`
* @from {@link Math `Math`}
* @example
* ```ts
* const v = $(1.7).floor().value;
* expect(v).toBe(1);
* ```
*/
floor: () => Return<Floor<T>, typeof t>;
/**
* `Math.ceil(x)`
* @from {@link Math `Math`}
* @example
* ```ts
* const v = $(1.3).ceil().value;
* expect(v).toBe(2);
* ```
*/
ceil: () => Return<Ceil<T>, typeof t>;
/**
* `Math.round(x)`
* @see `.snapped()` for a rounding with customizable precision
* @from {@link Math `Math`}
* @example
* ```ts
* const a = $(1.3).round().value;
* const b = $(1.7).round().value;
*
* expect(a).toBe(1);
* expect(b).toBe(2);
* ```
*/
round: () => Return<Round<T>, typeof t>;
/**
* `Math.fround(x)`, round to the nearest 32-bit float
* approximation of value
* @from {@link Math `Math`}
* @example
* ```ts
* const v = $(0.99999999).fround().value;
* expect(v).toBe(1);
* ```
*/
fround: () => Return<number, typeof t>;
/**
* `Math.abs(x)`, calculate the absolute value (distance
* from 0).
* @from {@link Math `Math`}
* @example
* ```ts
* const v = 4 as const;
*
* const a = $(v).abs().value;
* const b = $(-v).abs().value;
*
* expect(a).toBe(v);
* expect(b).toBe(v);
* ```
*/
abs: () => Return<
`${T}` extends `-${infer N extends number}`
? N
: T,
typeof t
>;
/**
* `-x` or alternatively `x * -1`
* @from {@link Math `Math`}
* @example
* ```ts
* const v = 10 as const;
*
* const a = $(v).negate().value;
* expect(a).toBe(-v);
*
* const b = $(-v).negate().value;
* expect(b).toBe(v);
* ```
*/
negate: () => Return<Negate<T>, typeof t>;
/**
* `Math.sign(x)`, returns the sign of the value or zero
* @from {@link Math `Math`}
* @example
* ```ts
* const a = $(-42).sign().value;
* const b = $(0).sign().value;
* const c = $(99).sign().value;
*
* expect(a).toBe(-1);
* expect(b).toBe(0);
* expect(c).toBe(1);
* ```
*/
sign: () => Return<Sign<T>, typeof t>;
min: (
...others: number[]
) => Return<number, typeof t>;
max: (
...others: number[]
) => Return<number, typeof t>;
/**
* `Math.min(x, ...values)`, pick the _smallest_ out of the
* provided numbers
* @param others Other numbers
* @from {@link Math `Math`}
* @example
* ```ts
* const maximum = 10;
*
* const a = $(5).min(maximum).value;
* const b = $(15).min(maximum).value;
*
* expect(a).toBe(5);
* expect(b).toBe(10);
* ```
*/
min: <U extends [number, ...number[]]>(
/** Other numbers */
...others: U
) => Return<T | U[number], typeof t>;
/**
* `Math.max(x, ...values)`, pick the _largest_ out of the
* provided numbers
* @param others Other numbers
* @from {@link Math `Math`}
* @example
* ```ts
* const minimum = 0;
*
* const a = $(5).max(minimum).value;
* const b = $(-5).max(minimum).value;
*
* expect(a).toBe(5);
* expect(b).toBe(0);
* ```
*/
max: <U extends [number, ...number[]]>(
/** Other numbers */
...others: U
) => Return<T | U[number], typeof t>;
/**
* Clamp value to be within the specified range, or
* alternatively the form of `Math.min(Math.max(x, min),
* max)`.
* @param min Start of the range, the smallest that the value can be
* @param max End of the range, the largest that the value can be
* @from {@link Math `Math`}
* @example
* ```ts
* const min = 0;
* const max = 10;
*
* const a = $(5).clamp(min, max).value;
* const b = $(-2).clamp(min, max).value;
* const c = $(15).clamp(min, max).value;
*
* expect(a).toBe(5);
* expect(b).toBe(0);
* expect(c).toBe(10);
* ```
*/
clamp: (
/** The minimum (smallest) value of the range */
min: number,
/** The maximum (largest) value of the range */
max: number,
) => Return<number, typeof t>;
/**
* Snap or round value to a nearest multiple of the
* specified unit
* @param multiple The unit to snap to
* @from {@link Math `Math`}
* @example
* ```ts
* const unit = 32;
*
* const a = $(32).snapped(unit).value;
* const b = $(48).snapped(unit).value;
* const c = $(64).snapped(unit).value;
*
* expect(a).toBe(32);
* expect(b).toBe(64);
* expect(c).toBe(64);
* ```
*/
snapped: (
/** Unit to snap to */
multiple: number,
) => Return<number, typeof t>;
/**
* Calculate the linear interpolation of value (`a`) to the
* specified target value (`b`) at the specified point
* (`t`).
*
* Alternative forms: `lerp(a, b, t)` or `a * (1 - t) +
* b * t`
* @param b Target value to interpolate to
* @param t Interpolation factor, 0 is `a` and 1 is `b`
* @from {@link Math `Math`}
* @example
* ```ts
* const from = 12;
* const to = 8;
*
* const a = $(from).lerp(to, 0).value;
* const b = $(from).lerp(to, 0.5).value;
* const c = $(from).lerp(to, 1).value;
*
* expect(a).toBe(12);
* expect(b).toBe(10);
* expect(c).toBe(8);
*
* const d = $(from).lerp(to, -1).value;
* const e = $(from).lerp(to, 2).value;
*
* expect(d).toBe(16);
* expect(e).toBe(4);
* ```
*/
lerp: typeof t extends infer TProps extends Props
? (
/** Target value */
b: number,
/** Interpolation factor, 0 is representative of `a` and 1 is representative of `b` */
t: number,
) => Return<number, TProps>
: never;
/**
* `Math.sin(x)`
* @from {@link Math `Math`}
*/
sin: () => Return<number, typeof t>;
/**
* `Math.asin(x)`
* @from {@link Math `Math`}
*/
asin: () => Return<number, typeof t>;
/**
* `Math.cos(x)`
* @from {@link Math `Math`}
*/
cos: () => Return<number, typeof t>;
/**
* `Math.acos(x)`
* @from {@link Math `Math`}
*/
acos: () => Return<number, typeof t>;
/**
* `Math.tan(x)`
* @from {@link Math `Math`}
*/
tan: () => Return<number, typeof t>;
/**
* `Math.atan(x)`
* @from {@link Math `Math`}
*/
atan: () => Return<number, typeof t>;
/**
* `Math.atan2(x, y)`
* @from {@link Math `Math`}
*/
atan2: (y: number) => Return<number, typeof t>;
/**
* `Math.sinh(x)`
* @from {@link Math `Math`}
*/
sinh: () => Return<number, typeof t>;
/**
* `Math.asinh(x)`
* @from {@link Math `Math`}
*/
asinh: () => Return<number, typeof t>;
/**
* `Math.cosh(x)`
* @from {@link Math `Math`}
*/
cosh: () => Return<number, typeof t>;
/**
* `Math.acosh(x)`
* @from {@link Math `Math`}
*/
acosh: () => Return<number, typeof t>;
/**
* `Math.tanh(x)`
* @from {@link Math `Math`}
*/
tanh: () => Return<number, typeof t>;
/**
* `Math.atanh(x)`
* @from {@link Math `Math`}
*/
atanh: () => Return<number, typeof t>;
to: {
/**
* Convert angle to representation in radians (`1 *
* Math.PI` radians per `1 * 180` degrees)
* @from {@link Math `Math`}
* @example
* ```ts
* const v = $(360).to.radians().value;
* expect(v).toBe(2 * Math.PI);
* ```
*/
radians: () => Return<number, typeof t>;
/**
* Convert angle to representation in degrees (`1 * 180`
* degrees per `1 * Math.PI` radians)
* @from {@link Math `Math`}
* @example
* ```ts
* const v = $(2 * Math.PI).to.degrees().value;
* expect(v).toBe(360);
* ```
*/
degrees: () => Return<number, typeof t>;
};
}