fix type inferencing bug
This commit is contained in:
parent
69175c8cb1
commit
b2584a2495
2 changed files with 12 additions and 7 deletions
|
|
@ -97,7 +97,7 @@ function InputParams({ ...rest }) {
|
||||||
const globalContext = useContext(GlobalContext);
|
const globalContext = useContext(GlobalContext);
|
||||||
const typeInfo = inferTypeCall(rest.state, env);
|
const typeInfo = inferTypeCall(rest.state, env);
|
||||||
const inputEnv = typeInfo.fn.newEnv;
|
const inputEnv = typeInfo.fn.newEnv;
|
||||||
const isOffending = rest.state.err;
|
const isOffending = typeInfo.err;
|
||||||
return <div className={"inputParam" + (isOffending ? " offending" : "")}>
|
return <div className={"inputParam" + (isOffending ? " offending" : "")}>
|
||||||
{rest.state.fn.kind === "call"
|
{rest.state.fn.kind === "call"
|
||||||
&& globalContext?.syntacticSugar
|
&& globalContext?.syntacticSugar
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,6 @@ export function inferTypeInput(s: InputBlockState, env: Environment): TypeInfoIn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
export function inferTypeCall(s: CallBlockState, env: Environment): TypeInfoCall {
|
export function inferTypeCall(s: CallBlockState, env: Environment): TypeInfoCall {
|
||||||
const fnTypeInfo = inferType(s.fn, env);
|
const fnTypeInfo = inferType(s.fn, env);
|
||||||
const inputEnv = fnTypeInfo.newEnv;
|
const inputEnv = fnTypeInfo.newEnv;
|
||||||
|
|
@ -112,7 +111,6 @@ export function inferTypeCall(s: CallBlockState, env: Environment): TypeInfoCall
|
||||||
const subs = unify(
|
const subs = unify(
|
||||||
fnTypeInfo.type,
|
fnTypeInfo.type,
|
||||||
fakeFnType);
|
fakeFnType);
|
||||||
// console.log("subs:", prettySS(subs));
|
|
||||||
let type, newEnv;
|
let type, newEnv;
|
||||||
if (subs.has(returnType!.symbol)) {
|
if (subs.has(returnType!.symbol)) {
|
||||||
type = subs.get(returnType!.symbol);
|
type = subs.get(returnType!.symbol);
|
||||||
|
|
@ -159,6 +157,7 @@ export function inferTypeCall(s: CallBlockState, env: Environment): TypeInfoCall
|
||||||
input: inputTypeInfo,
|
input: inputTypeInfo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -195,13 +194,13 @@ export function inferTypeLambda(s: LambdaBlockState, env: Environment): TypeInfo
|
||||||
const subsWithoutPType = new Map(innerTypeInfo.subs);
|
const subsWithoutPType = new Map(innerTypeInfo.subs);
|
||||||
subsWithoutPType.delete(paramTypeVar);
|
subsWithoutPType.delete(paramTypeVar);
|
||||||
const inferredPType = substitute(paramType, innerTypeInfo.subs, []);
|
const inferredPType = substitute(paramType, innerTypeInfo.subs, []);
|
||||||
const inferredPType2 = rewriteInferredType(inferredPType, env);
|
const [inferredPType2, newEnv] = rewriteInferredType(inferredPType, env);
|
||||||
if (eqType(inferredPType2)(paramType)) {
|
if (eqType(inferredPType2)(paramType)) {
|
||||||
return {
|
return {
|
||||||
kind: "lambda",
|
kind: "lambda",
|
||||||
type: fnType(_ => paramType)(_ => innerTypeInfo.type),
|
type: fnType(_ => paramType)(_ => innerTypeInfo.type),
|
||||||
subs: subsWithoutPType,
|
subs: subsWithoutPType,
|
||||||
newEnv: env, // no change
|
newEnv,
|
||||||
paramType,
|
paramType,
|
||||||
inner: innerTypeInfo,
|
inner: innerTypeInfo,
|
||||||
innerEnv,
|
innerEnv,
|
||||||
|
|
@ -245,8 +244,9 @@ function typeUnknown(env: Environment): [Type, Environment] {
|
||||||
};
|
};
|
||||||
return [type, newEnv];
|
return [type, newEnv];
|
||||||
}
|
}
|
||||||
function rewriteInferredType(type: Type, env: Environment) {
|
function rewriteInferredType(type: Type, env: Environment): [Type, Environment] {
|
||||||
const substitutions = new Map();
|
const substitutions = new Map();
|
||||||
|
const newTypeVars = new Set(env.typevars);
|
||||||
let i = 0;
|
let i = 0;
|
||||||
for (const o of occurring(type)) {
|
for (const o of occurring(type)) {
|
||||||
while (env.typevars.has(UNBOUND_SYMBOLS[i])) {
|
while (env.typevars.has(UNBOUND_SYMBOLS[i])) {
|
||||||
|
|
@ -254,9 +254,14 @@ function rewriteInferredType(type: Type, env: Environment) {
|
||||||
}
|
}
|
||||||
if (!env.typevars.has(o)) {
|
if (!env.typevars.has(o)) {
|
||||||
substitutions.set(o, TYPE_VARS[i]);
|
substitutions.set(o, TYPE_VARS[i]);
|
||||||
|
newTypeVars.add(UNBOUND_SYMBOLS[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return substitute(type, substitutions, []);
|
const rewrittenType = substitute(type, substitutions, []);
|
||||||
|
return [rewrittenType, {
|
||||||
|
names: env.names,
|
||||||
|
typevars: env.typevars.union(newTypeVars),
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
export function scoreTypeInfo(typeInfo: TypeInfo): number {
|
export function scoreTypeInfo(typeInfo: TypeInfo): number {
|
||||||
const bias = typeInfo.err ? -1 : 0;
|
const bias = typeInfo.err ? -1 : 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue