much improved type inferencing

This commit is contained in:
Joeri Exelmans 2025-05-19 15:01:30 +02:00
parent 28e5032923
commit d877b42a12
5 changed files with 150 additions and 103 deletions

View file

@ -1,13 +1,14 @@
import { useContext, useEffect, useRef } from "react";
import { growEnv } from "dope2";
import { eqType, getSymbol, reduceUnification, trie } from "dope2";
import { ExprBlock, type ExprBlockState, type State2Props } from "./ExprBlock";
import { EnvContext } from "./EnvContext";
import { getUnusedTypeVar } from "./eval";
import { evalEditorBlock, makeInnerEnv, makeTypeVar } from "./eval";
import { autoInputWidth } from "./util/dom_trickery";
import "./LambdaBlock.css";
import { Type } from "./Type";
export interface LambdaBlockState {
kind: "lambda";
@ -47,11 +48,20 @@ export function LambdaBlock({state, setState, suggestionPriority}: LambdaBlockPr
useEffect(() => autoInputWidth(nameRef, state.paramName, 60), [nameRef, state.paramName]);
const innerEnv = growEnv(env)(state.paramName)({
kind: "unknown",
i: undefined,
t: getUnusedTypeVar(env),
});
const [paramType, staticInnerEnv] = makeTypeVar(env, state.paramName);
const exprResolved = evalEditorBlock(state.expr, staticInnerEnv);
const inferredParamType = reduceUnification(exprResolved.unification).get(getSymbol(paramType)) || paramType;
const betterInnerEnv = eqType(paramType)(inferredParamType)
? staticInnerEnv
: makeInnerEnv(env, state.paramName, {
kind: "unknown",
t: inferredParamType,
unification: new Map(), // <- is this correct?
})
return <span className="lambdaBlock">
<span className="keyword">&#955;</span>
@ -66,11 +76,14 @@ export function LambdaBlock({state, setState, suggestionPriority}: LambdaBlockPr
onChange={e => setParamName(e.target.value)}
/>
</span>
<div className="typeSignature">
&nbsp;::&nbsp;<Type type={inferredParamType} />
</div>
&nbsp;
<span className="keyword">:</span>
&nbsp;
<div className="lambdaInner">
<EnvContext value={innerEnv}>
<EnvContext value={betterInnerEnv}>
<ExprBlock
state={state.expr}
setState={setExpr}