eval lambda block: bubble up substitutions
This commit is contained in:
parent
496463bbac
commit
51ff4d24b0
3 changed files with 23 additions and 15 deletions
|
|
@ -1,5 +1,9 @@
|
||||||
.lambdaExpr {
|
.lambdaBlock {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
border: solid 1px darkgrey;
|
border: solid 1px darkgrey;
|
||||||
margin: 2px;
|
margin: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lambdaInner {
|
||||||
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
@ -56,7 +56,7 @@ export function LambdaBlock({state, setState, suggestionPriority}: LambdaBlockPr
|
||||||
t: getUnusedTypeVar(env),
|
t: getUnusedTypeVar(env),
|
||||||
});
|
});
|
||||||
|
|
||||||
return <span>
|
return <span className="lambdaBlock">
|
||||||
<span className="keyword">λ</span>
|
<span className="keyword">λ</span>
|
||||||
|
|
||||||
<span className="lambdaInputParam">
|
<span className="lambdaInputParam">
|
||||||
|
|
@ -72,7 +72,7 @@ export function LambdaBlock({state, setState, suggestionPriority}: LambdaBlockPr
|
||||||
|
|
||||||
<span className="keyword">:</span>
|
<span className="keyword">:</span>
|
||||||
|
|
||||||
<div className="lambdaExpr">
|
<div className="lambdaInner">
|
||||||
<EnvContext value={innerEnv}>
|
<EnvContext value={innerEnv}>
|
||||||
<Editor
|
<Editor
|
||||||
state={state.expr}
|
state={state.expr}
|
||||||
|
|
|
||||||
28
src/eval.ts
28
src/eval.ts
|
|
@ -98,6 +98,9 @@ export function evalCallBlock2(fnResolved: ResolvedType, inputResolved: Resolved
|
||||||
try {
|
try {
|
||||||
// fn is a function...
|
// fn is a function...
|
||||||
const [outType, substitutions] = assignFnSubstitutions(fnResolved.t, inputResolved.t); // may throw
|
const [outType, substitutions] = assignFnSubstitutions(fnResolved.t, inputResolved.t); // may throw
|
||||||
|
|
||||||
|
// console.log('assignFn...', prettyT(fnResolved.t), prettyT(inputResolved.t), '\nout =', prettyT(outType), substitutions);
|
||||||
|
|
||||||
|
|
||||||
const mergedSubstitutions = mergeMaps(substitutions, fnResolved.substitutions, inputResolved.substitutions);
|
const mergedSubstitutions = mergeMaps(substitutions, fnResolved.substitutions, inputResolved.substitutions);
|
||||||
|
|
||||||
|
|
@ -177,11 +180,21 @@ export function getUnusedTypeVar(env) {
|
||||||
|
|
||||||
export function evalLambdaBlock(paramName: string, expr: EditorState, env): ResolvedType {
|
export function evalLambdaBlock(paramName: string, expr: EditorState, env): ResolvedType {
|
||||||
const paramType = getUnusedTypeVar(env);
|
const paramType = getUnusedTypeVar(env);
|
||||||
|
// static env: we only know the name and the type
|
||||||
|
const staticInnerEnv = makeInnerEnv(env, paramName, {
|
||||||
|
kind: "unknown", // parameter value is not statically known
|
||||||
|
t: paramType,
|
||||||
|
substitutions: new Map(),
|
||||||
|
});
|
||||||
|
const exprResolved = evalEditorBlock(expr, staticInnerEnv);
|
||||||
|
const lambdaT = fnType(_ => paramType)(_ => exprResolved.t);
|
||||||
|
const lambdaTSubstituted = substitute(lambdaT, exprResolved.substitutions, []);
|
||||||
|
const paramTypeSubstituted = lambdaTSubstituted.params[0](lambdaTSubstituted);
|
||||||
const fn = (x: any) => {
|
const fn = (x: any) => {
|
||||||
const innerEnv = makeInnerEnv(env, paramName, {
|
const innerEnv = makeInnerEnv(env, paramName, {
|
||||||
kind: "value",
|
kind: "value",
|
||||||
i: x,
|
i: x,
|
||||||
t: paramType,
|
t: paramTypeSubstituted,
|
||||||
substitutions: new Map(),
|
substitutions: new Map(),
|
||||||
});
|
});
|
||||||
const result = evalEditorBlock(expr, innerEnv);
|
const result = evalEditorBlock(expr, innerEnv);
|
||||||
|
|
@ -189,20 +202,11 @@ export function evalLambdaBlock(paramName: string, expr: EditorState, env): Reso
|
||||||
return result.i;
|
return result.i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// static env: we only know the name and the type
|
|
||||||
const staticInnerEnv = makeInnerEnv(env, paramName, {
|
|
||||||
kind: "unknown", // parameter value is not statically known
|
|
||||||
t: paramType,
|
|
||||||
substitutions: new Map(),
|
|
||||||
});
|
|
||||||
const abstractOutput = evalEditorBlock(expr, staticInnerEnv);
|
|
||||||
const t = fnType(_ => paramType)(_ => abstractOutput.t);
|
|
||||||
const T = substitute(t, abstractOutput.substitutions, [])
|
|
||||||
return {
|
return {
|
||||||
kind: "value",
|
kind: "value",
|
||||||
t: T,
|
t: lambdaTSubstituted,
|
||||||
i: fn,
|
i: fn,
|
||||||
substitutions: new Map(),
|
substitutions: exprResolved.substitutions,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue