import type { Nat } from "."; import type { _CompareDigit } from "./internal/_CompareDigit"; import type { _CompareSDigit } from "./internal/_CompareSDigit"; import type { _CompareStrLength } from "./internal/_CompareStrLength"; import type { SDigit } from ".."; import type { Arg0, Arg1, Fn } from "../../HKT"; import type { AssertOrdering } from "../../helpers"; import type { EQ, Ordering } from "../../typeclass/Ord"; /** * Compare two string representations of {@link Nat}s. * * **⚠️ Warning:** `N` must be of the same length as `M`. * @private */ type _CompareSNatRec = N extends `${infer F extends SDigit}${infer R}` ? M extends `${infer G extends SDigit}${infer S}` ? _CompareSDigit extends EQ ? _CompareSNatRec : _CompareSDigit : never : EQ; /** * Compare two {@link Nat}s. * * Sig: `(n: Nat, m: Nat) => Ordering` */ export type Compare = AssertOrdering< N extends M ? EQ : _CompareStrLength<`${N}`, `${M}`> extends infer O extends Ordering ? O extends EQ ? _CompareSNatRec<`${N}`, `${M}`> : O : never >; /** * [Fn] Compare two {@link Nat}s. * * Sig: `(n: Nat, m: Nat) => Ordering` */ export default interface CompareFn extends Fn<[Nat, Nat], Ordering> { def: () => Compare, Arg1>; }