correct suggestion order also in body of lambda function
This commit is contained in:
parent
1ff4b181ff
commit
24689b3783
7 changed files with 24 additions and 15 deletions
|
|
@ -166,7 +166,10 @@ export function App() {
|
||||||
state={appState.history.at(-1)!}
|
state={appState.history.at(-1)!}
|
||||||
setState={pushHistory}
|
setState={pushHistory}
|
||||||
onCancel={() => {}}
|
onCancel={() => {}}
|
||||||
suggestionPriority={() => 1}
|
suggestionPriority={() => {
|
||||||
|
// console.log('suggestionPriority of App, always 0');
|
||||||
|
return 0;
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</GlobalContext>
|
</GlobalContext>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { useContext } from "react";
|
||||||
|
|
||||||
import "./CallBlock.css";
|
import "./CallBlock.css";
|
||||||
import { Editor, type EditorState, type SetStateFn, type State2Props } from "./Editor";
|
import { Editor, type EditorState, type SetStateFn, type State2Props } from "./Editor";
|
||||||
import { EnvContext } from "./EnvContext";
|
import { EnvContext, functionWith3Params, functionWith4Params } from "./EnvContext";
|
||||||
import { evalCallBlock2, evalEditorBlock, scoreResolved, type ResolvedType } from "./eval";
|
import { evalCallBlock2, evalEditorBlock, scoreResolved, type ResolvedType } from "./eval";
|
||||||
import { Value } from "./Value";
|
import { Value } from "./Value";
|
||||||
import { GlobalContext } from "./GlobalContext";
|
import { GlobalContext } from "./GlobalContext";
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,10 @@
|
||||||
border: 1px solid red;
|
border: 1px solid red;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
.editor.unknown {
|
||||||
|
border: 1px dashed dodgerblue;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
.offending .error {
|
.offending .error {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
|
|
||||||
|
|
@ -183,7 +183,7 @@ export function Editor({state, setState, onCancel, suggestionPriority}: EditorPr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const resolved = evalEditorBlock(state, env);
|
const resolved = evalEditorBlock(state, env);
|
||||||
return <span className={"editor" + ((resolved.kind==="error") ? " error" : "")}>
|
return <span className={"editor" + ((resolved.kind!=="value") ? " "+resolved.kind : "")}>
|
||||||
{renderBlock()}
|
{renderBlock()}
|
||||||
<div className="typeSignature">
|
<div className="typeSignature">
|
||||||
:: <Type type={getType(resolved)} />
|
:: <Type type={getType(resolved)} />
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
import { createContext } from "react";
|
import { createContext } from "react";
|
||||||
import { getDefaultTypeParser, module2Env, ModuleStd } from "dope2";
|
import { getDefaultTypeParser, module2Env, ModuleStd } from "dope2";
|
||||||
|
|
||||||
|
export const functionWith3Params = i => j => k => i+j+k;
|
||||||
|
export const functionWith4Params = i => j => k => l => i+j+k+l;
|
||||||
|
|
||||||
const mkType = getDefaultTypeParser();
|
const mkType = getDefaultTypeParser();
|
||||||
export const extendedEnv = module2Env(ModuleStd.concat([
|
export const extendedEnv = module2Env(ModuleStd.concat([
|
||||||
["functionWith3Params", { i: i => j => k => i + j + k, t: mkType("Int->Int->Int->Int") }],
|
["functionWith3Params", { i: functionWith3Params, t: mkType("Int->Int->Int->Int") }],
|
||||||
["functionWith4Params", { i: i => j => k => l => i+j+k+l, t: mkType("Int->Int->Int->Int->Int")}]
|
["functionWith4Params", { i: functionWith4Params, t: mkType("Int->Int->Int->Int->Int")}]
|
||||||
]));
|
]));
|
||||||
|
|
||||||
export const EnvContext = createContext(extendedEnv);
|
export const EnvContext = createContext(extendedEnv);
|
||||||
|
|
@ -4,7 +4,7 @@ import { growEnv } from "dope2";
|
||||||
|
|
||||||
import { Editor, type EditorState, type State2Props } from "./Editor";
|
import { Editor, type EditorState, type State2Props } from "./Editor";
|
||||||
import { EnvContext } from "./EnvContext";
|
import { EnvContext } from "./EnvContext";
|
||||||
import { getUnusedTypeVar } from "./eval";
|
import { evalEditorBlock, getUnusedTypeVar, type ResolvedType } from "./eval";
|
||||||
import { autoInputWidth } from "./util/dom_trickery";
|
import { autoInputWidth } from "./util/dom_trickery";
|
||||||
|
|
||||||
import "./LambdaBlock.css";
|
import "./LambdaBlock.css";
|
||||||
|
|
@ -77,7 +77,10 @@ export function LambdaBlock({state, setState, suggestionPriority}: LambdaBlockPr
|
||||||
state={state.expr}
|
state={state.expr}
|
||||||
setState={setExpr}
|
setState={setExpr}
|
||||||
onCancel={() => setState(state => state.expr)}
|
onCancel={() => setState(state => state.expr)}
|
||||||
suggestionPriority={suggestionPriority}
|
suggestionPriority={(s) => {
|
||||||
|
// console.log('suggestionPriority of lambdaInner... just passing through');
|
||||||
|
return suggestionPriority(s);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</EnvContext>
|
</EnvContext>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
10
src/eval.ts
10
src/eval.ts
|
|
@ -86,9 +86,6 @@ const mergeMaps = (...maps: Map<Type,Type>[]) => {
|
||||||
|
|
||||||
export function evalCallBlock2(fnResolved: ResolvedType, inputResolved: ResolvedType, env): ResolvedType {
|
export function evalCallBlock2(fnResolved: ResolvedType, inputResolved: ResolvedType, env): ResolvedType {
|
||||||
if (getSymbol(fnResolved.t) !== symbolFunction) {
|
if (getSymbol(fnResolved.t) !== symbolFunction) {
|
||||||
if (fnResolved.kind === "unknown") {
|
|
||||||
return entirelyUnknown(env); // don't flash everything red, giving the user a heart attack
|
|
||||||
}
|
|
||||||
// worst outcome: we know nothing about the result!
|
// worst outcome: we know nothing about the result!
|
||||||
return {
|
return {
|
||||||
kind: "error",
|
kind: "error",
|
||||||
|
|
@ -102,8 +99,7 @@ export function evalCallBlock2(fnResolved: ResolvedType, inputResolved: Resolved
|
||||||
// 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);
|
// console.log('assignFn...', prettyT(fnResolved.t), inputResolved.i, prettyT(inputResolved.t), '\nout =', prettyT(outType), substitutions);
|
||||||
|
|
||||||
|
|
||||||
const mergedSubstitutions = mergeMaps(substitutions, fnResolved.substitutions, inputResolved.substitutions);
|
const mergedSubstitutions = mergeMaps(substitutions, fnResolved.substitutions, inputResolved.substitutions);
|
||||||
|
|
||||||
|
|
@ -286,10 +282,10 @@ export function scoreResolved(resolved: ResolvedType, outPriority: (s:ResolvedTy
|
||||||
const bias = outPriority(resolved);
|
const bias = outPriority(resolved);
|
||||||
|
|
||||||
if (resolved.kind === "value") {
|
if (resolved.kind === "value") {
|
||||||
return 1 + bias;
|
return 2 + bias;
|
||||||
}
|
}
|
||||||
else if (resolved.kind === "unknown") {
|
else if (resolved.kind === "unknown") {
|
||||||
return 0 + bias;
|
return 1 + bias;
|
||||||
}
|
}
|
||||||
if (resolved.e instanceof UnifyError) {
|
if (resolved.e instanceof UnifyError) {
|
||||||
return -1 + bias; // parameter doesn't match
|
return -1 + bias; // parameter doesn't match
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue