import type { ApplyW, Args, Call1W, Fn, Fn1, GenericReturnW, Param0, Params } from "./HKT"; type GetBranches = _GetBranches>; type _GetBranches = TS extends readonly [infer Head, ...infer Tail] ? readonly [Fn1, ..._GetBranches] : readonly []; type GetBranch = GetBranches[I] extends infer B extends Fn1 ? B : never; type GetReturnFnParamType = Branches extends readonly [infer Head extends Fn1, ...infer Tail extends Fn1[]] ? Param0 & GetReturnFnParamType : unknown; type GetBranchesParams = Branches extends readonly [infer Head extends Fn1, ...infer Tail extends Fn1[]] ? readonly [Param0, ...GetBranchesParams] : readonly []; type CallBranches = Branches extends readonly [infer Head extends Fn1, ...infer Tail extends Fn1[]] ? [Call1W, ...CallBranches] : []; type FilterOutNevers = TS extends readonly [infer Head, ...infer Tail] ? [Head] extends [never] ? FilterOutNevers : readonly [Head, ...FilterOutNevers] : TS; /** * [Fn] Accepts a converging function and a list of branching functions and returns a new function. * * Sig: `(converging: (x1: X1, x2: X2, ...) => R, ...branches: [(a: A) => X1, (b: B) => X2, ...]) => (x: A & B & ...) => R` */ export interface Converge< Converging extends Fn, Branch1 extends GetBranch = never, Branch2 extends GetBranch = never, Branch3 extends GetBranch = never, Branch4 extends GetBranch = never, > extends Fn< [GetReturnFnParamType>], GenericReturnW< Converging, GetBranchesParams> > > { def: ([x]: Args) => ApplyW< Converging, CallBranches, typeof x> >; }