UNPKG

rivo

Version:

🤖 The ultimate library you need for composable type-level programming in TypeScript, powered by HKT.

87 lines (81 loc) • 3.33 kB
import type { SDigit } from "."; import type { Abs } from "./Abs"; import type { IsNeg } from "./IsNeg"; import type { IsPos } from "./IsPos"; import type { _CompareSDigit } from "./Nat/internal/_CompareSDigit"; import type { Arg0, Arg1, Fn } from "../HKT"; import type { ToChars } from "../Str/ToChars"; import type { And, AssertOrdering } from "../helpers"; import type { EQ, GT, LT, Ordering } from "../typeclass/Ord"; type _ToFloat<N extends number> = `${N}` extends `${infer A}.${infer B}` ? readonly [A, B] : readonly [`${N}`, "0"]; type _CompareSDigits<NS extends readonly SDigit[], MS extends readonly SDigit[]> = NS extends readonly [infer AHead extends SDigit, ...infer ATail extends readonly SDigit[]] ? MS extends readonly [infer BHead extends SDigit, ...infer BTail extends readonly SDigit[]] ? _CompareSDigit<AHead, BHead> extends 0 ? _CompareSDigits<ATail, BTail> : _CompareSDigit<AHead, BHead> : _CompareSDigit<AHead, "0"> : EQ; type _CompareListLength<NS extends readonly unknown[], MS extends readonly unknown[]> = NS extends readonly [unknown, ...infer ATail extends readonly unknown[]] ? MS extends readonly [unknown, ...infer BTail extends readonly unknown[]] ? _CompareListLength<ATail, BTail> : GT : MS extends readonly [unknown, ...(readonly unknown[])] ? LT : EQ; /** * Compare two numbers. * * Sig: `(n: number, m: number) => Ordering` */ export type Compare<N extends number, M extends number> = AssertOrdering< [N] extends [never] ? never : [M] extends [never] ? never : And<IsPos<N>, IsNeg<M>> extends true ? GT : And<IsNeg<N>, IsPos<M>> extends true ? LT : ( Abs<N> extends infer N extends number ? Abs<M> extends infer M extends number ? readonly [_ToFloat<N>, _ToFloat<M>] extends readonly [infer NFloat, infer MFloat] ? NFloat extends readonly [infer NInt extends string, infer NFrac extends string] ? MFloat extends readonly [infer MInt extends string, infer MFrac extends string] ? readonly [ ToChars<`${NInt}`>, ToChars<`${NFrac}`>, ToChars<`${MInt}`>, ToChars<`${MFrac}`>, ] extends ( readonly [ infer AIntDigits extends readonly SDigit[], infer AFracDigits extends readonly SDigit[], infer BIntDigits extends readonly SDigit[], infer BFracDigits extends readonly SDigit[], ] ) ? _CompareListLength<AIntDigits, BIntDigits> extends EQ ? _CompareSDigits<AIntDigits, BIntDigits> extends EQ ? _CompareSDigits<AFracDigits, BFracDigits> : _CompareSDigits<AIntDigits, BIntDigits> : _CompareListLength<AIntDigits, BIntDigits> : never : never : never : never : never : never ) extends infer R extends Ordering ? And<IsPos<N>, IsPos<M>> extends true ? R : R extends GT ? LT : R extends LT ? GT : R : never >; /** * [Fn] Compare two numbers. * * Sig: `(n: number, m: number) => Ordering` */ export default interface CompareFn extends Fn<[number, number], Ordering> { def: () => Compare<Arg0<this>, Arg1<this>>; }