import {} from "./typeLevelNats"; type GenericFunction = (...x: never[]) => unknown; type Assume = T extends U ? T : U; abstract class TypeFunc { readonly _1?: unknown; new: (_: Arg) => Ret; } type Apply, _1> = ReturnType< (F & { readonly _1: _1; })["new"] >; interface GetPrev extends TypeFunc, N> { new: (arg: Suc) => N; } // nat-elim : (M : T -> U) -> (cz : M z) -> (sz : (n : N) -> M n -> M (suc n)) -> (n : N) -> M n // (M : T -> U) -> (cz : M z) -> (sz : (n : N) -> M n -> M (suc n)) -> (n : N) -> M n // interface ConstNat extends TypeFunc { new: (_: any) => Nat; } interface DoubleSuc extends TypeFunc { new: (arg: Assume) => Suc>; } type NatElim0< M extends TypeFunc, ZCase, SCase extends TypeFunc< Nat, TypeFunc, Apply>> >, N > = /** --------------------------------------------------------------- */ N extends Zero // // if N matches Zero ? ZCase // return ZCase : N extends Suc // if N matches Suc(Prev) ? Apply< any /* TODO: */, any /* TODO: */, Apply< Nat, TypeFunc, Apply>>, SCase, Prev >, Apply > : never; interface DoubleNat extends TypeFunc { new: (arg: Nat) => NatElim0; } /* interface NatElim< MRet, M extends TypeFunc, ZCase extends Apply, Z>, SCase extends TypeFunc > extends TypeFunc { _unused: (_1: ZCase, _2: SCase) => never; new: (arg: Assume) => Apply; } type Two = S>; const realThree: S>> = S.s(); const realFour: S>>> = S.s(); function isFour>(_: F) {} isFour(realThree); isFour(realFour); */ ///// type Length = T extends { length: infer L } ? L : never; type BuildTuple = T extends { length: L; } ? T : BuildTuple; type Add = Length< [...BuildTuple, ...BuildTuple] >; type Equals = { eq: [T1, T2] }; type Seven = Add<3, 4>; // 7 function isSeven(s: Seven) {} isSeven(6); isSeven(7); /// class Eq { private a: (_: A) => A; private b: (_: B) => B; private constructor() {} static refl(): Eq { return new Eq(); } } function isEqual1(_: Eq<3, 3>) {} isEqual1(Eq.refl()); function isEqual2(_: Eq<3, 4>) {} isEqual2(Eq.refl()); function isEqual3(_: Eq, 7>) {} isEqual3(Eq.refl()); function isEqual4(_: Eq, 8>) {} isEqual4(Eq.refl()); /// type Commutative = Eq, Add>; function comm(): Commutative { return Eq.refl(); }