70 lines
1.8 KiB
TypeScript
70 lines
1.8 KiB
TypeScript
import { useContext } from "react";
|
|
|
|
import { EnvContext } from "../../context/EnvContext";
|
|
import { ExprBlock, type ExprBlockState, type State2Props } from "./ExprBlock";
|
|
|
|
import { type TypeInfoLambda } from "../../eval/infer_type";
|
|
import { Input } from "../other/Input";
|
|
import { Type } from "../other/Type";
|
|
import "./LambdaBlock.css";
|
|
|
|
export interface LambdaBlockState {
|
|
kind: "lambda";
|
|
paramName: string;
|
|
focus: boolean;
|
|
expr: ExprBlockState;
|
|
}
|
|
|
|
export interface LambdaBlockProps<
|
|
FnState=ExprBlockState,
|
|
InputState=ExprBlockState,
|
|
> extends State2Props<LambdaBlockState,ExprBlockState> {
|
|
typeInfo: TypeInfoLambda;
|
|
}
|
|
|
|
|
|
export function LambdaBlock({state, setState, score, typeInfo}: LambdaBlockProps) {
|
|
const env = useContext(EnvContext);
|
|
|
|
const setParamName = paramName => setState(state => ({
|
|
...state,
|
|
paramName,
|
|
}));
|
|
const setExpr = callback => setState(state => ({
|
|
...state,
|
|
expr: callback(state.expr),
|
|
}));
|
|
|
|
return <span className="lambdaBlock">
|
|
<span className="keyword">λ</span>
|
|
|
|
<span className="lambdaInputParam">
|
|
<Input
|
|
placeholder="<name>"
|
|
text={state.paramName}
|
|
suggestion=""
|
|
onEnter={() => {}}
|
|
onCancel={() => {}}
|
|
onTextChange={txt => setParamName(txt)}
|
|
extraHandlers={{}}
|
|
/>
|
|
</span>
|
|
<div className="typeSignature">
|
|
:: <Type type={typeInfo.paramType} />
|
|
</div>
|
|
|
|
<span className="keyword">:</span>
|
|
|
|
<div className="lambdaInner">
|
|
<EnvContext value={typeInfo.innerEnv}>
|
|
<ExprBlock
|
|
state={state.expr}
|
|
setState={setExpr}
|
|
onCancel={() => setState(state => state.expr)}
|
|
score={suggestion => score({...state, expr: suggestion})}
|
|
typeInfo={typeInfo.inner}
|
|
/>
|
|
</EnvContext>
|
|
</div>
|
|
</span>
|
|
}
|