import type { Nat } from "."; import type { _AddDigit } from "./internal/_AddDigit"; import type { _CompareDigit } from "./internal/_CompareDigit"; import type { _RemoveStrPaddingZeroes } from "./internal/_RemoveStrPaddingZeroes"; import type { _SubDigit } from "./internal/_SubDigit"; import type { Digit } from ".."; import type { Arg0, Arg1, Fn } from "../../HKT"; import type { Reverse } from "../../Str/Reverse"; import type { EQ, GT } from "../../typeclass/Ord"; import type { _StrToNum } from "../internal/_StrToNum"; /** * Subtract two {@link Nat}s. * * Sig: `(n: Nat, m: Nat) => Nat` * * **⚠️ Warning:** `N` must be greater than or equal to `M`. */ export type Sub = _StrToNum>; /** * Subtract two string representations of {@link Nat}s. * * **⚠️ Warning:** `N` must be greater than or equal to `M`. * @private */ type SSub = _RemoveStrPaddingZeroes< Reverse<_SSub, Reverse>> >; type _SSub< N extends string, M extends string, Borrow extends 0 | 1 = 0, Result extends string = "", > = N extends `${infer F extends Digit}${infer R}` ? M extends `${infer G extends Digit}${infer S}` ? Borrow extends 0 ? _CompareDigit extends EQ | GT ? _SSub}`> : // prettier-ignore _SSub, 1> extends infer U extends Digit ? U : never, F>}`> : F extends 0 ? _SSub}`> : _CompareDigit<_SubDigit, G> extends EQ | GT ? _SSub, G>}`> : // prettier-ignore _SSub, F>}`> : Borrow extends 1 ? `${Result}${_SSub}` : `${Result}${N}` : Borrow extends 1 ? `${Result}1` : Result; /** * [Fn] Subtract two {@link Nat}s. * * Sig: `(n: Nat, m: Nat) => Nat` * * **⚠️ Warning:** `N` must be greater than or equal to `M`. */ export default interface SubFn extends Fn<[Nat, Nat], Nat> { def: () => Sub, Arg1>; }