diff --git a/index.d.ts b/index.d.ts index d6192d9..1d1808b 100644 --- a/index.d.ts +++ b/index.d.ts @@ -177,7 +177,7 @@ export function apply(input: any): any; export function assignFn(funType: any, paramType: any): any; -export function assignFnSubstitutions(funType: any, paramType: any): [any, any]; +export function assignFnSubstitutions(funType: any, paramType: any, skip: number): [any, any, any, any]; export function capitalizeFirstLetter(val: any): any; diff --git a/lib/generics/generics.js b/lib/generics/generics.js index 10733c2..eed5c41 100644 --- a/lib/generics/generics.js +++ b/lib/generics/generics.js @@ -189,22 +189,24 @@ export const substitute = (type, substitutions, stack=[]) => { }; export const assignFn = (funType, paramType) => { - return assignFnSubstitutions(funType, paramType)[2]; + const [inType, inSubst, outType, outSubst] = assignFnSubstitutions(funType, paramType); + // return recomputeTypeVars([outType])[0]; + return outType; }; // same as above, but also returns the substitutions that took place -export const assignFnSubstitutions = (funType, paramType) => { +export const assignFnSubstitutions = (funType, paramType, skip=0) => { if (getSymbol(funType) !== symbolFunction) { throw new NotAFunctionError(`${prettyT(funType)} is not a function type!`); } - const [[refunType, funS], [reparamType, paramS]] = recomputeTypeVarsSubstitutions([funType, paramType]); - const recomputationSubstitutions = mergeTwoWay(funS, paramS); + const [[refunType, funS], [reparamType, paramS]] = recomputeTypeVarsSubstitutions([funType, paramType], skip); const [inType, outType] = refunType.params.map(p => p(refunType)); const {type: newInType, substitutions} = __unify(inType, reparamType); - const inTypeSubst = mergeTwoWay(substitutions, recomputationSubstitutions); - const substitutedFnType = substitute(outType, substitutions); - const [computedOutType, outSubst] = recomputeTypeVarsSubstitutions([substitutedFnType])[0]; - return [newInType, inTypeSubst, computedOutType, outSubst]; + const totalParamSubstitutions = mergeTwoWay(substitutions, paramS); + const newOutType = substitute(outType, substitutions); + const [[finalOutType, outsubst]] = recomputeTypeVarsSubstitutions([newOutType], skip); + const totalOutSubstitutions = mergeTwoWay(funS, outsubst); + return [newInType, totalParamSubstitutions, finalOutType, totalOutSubstitutions]; }; // Ensures that no type variables overlap @@ -213,8 +215,8 @@ export const recomputeTypeVars = types => { .map(([newType, _subst]) => newType); }; -export const recomputeTypeVarsSubstitutions = types => { - let nextIdx = 0; +export const recomputeTypeVarsSubstitutions = (types, skip=0) => { + let nextIdx = skip; return types.map(type => { const substitutions = new Map(); const typeVars = occurring(type);