UNPKG

rivo

Version:

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

63 lines (59 loc) 2.18 kB
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<N extends Nat, M extends Nat> = _StrToNum<SSub<`${N}`, `${M}`>>; /** * Subtract two string representations of {@link Nat}s. * * **⚠️ Warning:** `N` must be greater than or equal to `M`. * @private */ type SSub<N extends string, M extends string> = _RemoveStrPaddingZeroes< Reverse<_SSub<Reverse<N>, Reverse<M>>> >; 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<F, G> extends EQ | GT ? _SSub<R, S, 0, `${Result}${_SubDigit<F, G>}`> : // prettier-ignore _SSub<R, S, 1, `${Result}${_AddDigit<_AddDigit<_SubDigit<9, G>, 1> extends infer U extends Digit ? U : never, F>}`> : F extends 0 ? _SSub<R, S, 1, `${Result}${_SubDigit<9, G>}`> : _CompareDigit<_SubDigit<F, 1>, G> extends EQ | GT ? _SSub<R, S, 0, `${Result}${_SubDigit<_SubDigit<F, 1>, G>}`> : // prettier-ignore _SSub<R, S, 1, `${Result}${_AddDigit<_SubDigit<9, G>, F>}`> : Borrow extends 1 ? `${Result}${_SSub<N, "1">}` : `${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<Arg0<this>, Arg1<this>>; }