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 `${infer A}.${infer B}` ? readonly [A, B] : readonly [`${N}`, "0"]; type _CompareSDigits = 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 extends 0 ? _CompareSDigits : _CompareSDigit : _CompareSDigit : EQ; type _CompareListLength = NS extends readonly [unknown, ...infer ATail extends readonly unknown[]] ? MS extends readonly [unknown, ...infer BTail extends readonly unknown[]] ? _CompareListLength : GT : MS extends readonly [unknown, ...(readonly unknown[])] ? LT : EQ; /** * Compare two numbers. * * Sig: `(n: number, m: number) => Ordering` */ export type Compare = AssertOrdering< [N] extends [never] ? never : [M] extends [never] ? never : And, IsNeg> extends true ? GT : And, IsPos> extends true ? LT : ( Abs extends infer N extends number ? Abs extends infer M extends number ? readonly [_ToFloat, _ToFloat] 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 extends EQ ? _CompareSDigits extends EQ ? _CompareSDigits : _CompareSDigits : _CompareListLength : never : never : never : never : never : never ) extends infer R extends Ordering ? And, IsPos> 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, Arg1>; }