visualize type unification substitutions

This commit is contained in:
Joeri Exelmans 2025-05-27 11:17:32 +02:00
parent 4a4cee6ee9
commit 7edf44f107
7 changed files with 45 additions and 40 deletions

View file

@ -9,7 +9,7 @@ import { biggerExample, emptySet, factorial, higherOrder, higherOrder2Params, in
import './App.css';
import { evalExpr } from '../../eval/eval';
import { Value } from '../other/Value';
import { Type } from '../other/Type';
import { Type, TypeInfoBlock } from '../other/Type';
const examples: [string, ExprBlockState][] = [
@ -190,7 +190,7 @@ export function App() {
t: typeInfo.type,
}}/>
::
<Type type={typeInfo.type}/>
<TypeInfoBlock typeInfo={typeInfo}/>
</GlobalContext>
</main>

View file

@ -5,7 +5,7 @@ import { EnvContext } from "../../context/EnvContext";
import { GlobalContext } from "../../context/GlobalContext";
import { type StaticEnvironment, type TypeInfoCall } from "../../eval/infer_type";
import { getActions } from "../app/actions";
import { Type } from "../other/Type";
import { Type, TypeInfoBlock } from "../other/Type";
import "./CallBlock.css";
import { ExprBlock, type ExprBlockState, type SetStateFn, type State2Props } from "./ExprBlock";
@ -67,7 +67,7 @@ export function CallBlock(props: CallBlockProps) {
{/* { (resolved.kind === "error") && resolved.e.toString()
|| (resolved.kind === "value") && <Value dynamic={resolved} />
|| "unknown" } */}
:: <Type type={props.typeInfo.type} />
:: <TypeInfoBlock typeInfo={props.typeInfo} />
</div>
</div>
</CallContext>

View file

@ -19,37 +19,6 @@
background-color: transparent;
}
.typeSignature {
display: inline-block;
/* z-index: 1; */
position: relative;
}
.typeSignature.gotDebug {
background-color: gold;
padding: 2px;
}
.typeDebug {
display: none;
}
.typeSignature:hover > .typeDebug {
display: inline-block;
position: absolute;
white-space-collapse: preserve;
width: max-content;
background-color: #d2ebf1e0;
color: black;
font-family: var(--my-monospace-font);
padding: 4px;
z-index: 1000;
}
.editor:hover > .typeSignature {
display: inline-block;
}
.keyword {
color: blue;
font-weight: bold;

View file

@ -8,7 +8,7 @@ import { GlobalContext } from "../../context/GlobalContext";
import { inferTypeInput, type StaticEnvironment, type Type, type TypeInfoInput } from "../../eval/infer_type";
import { getActions } from "../app/actions";
import { Input } from "../other/Input";
import { Type as TypeBlock } from "../other/Type";
import { Type as TypeBlock, TypeInfoBlock } from "../other/Type";
import type { ExprBlockState, State2Props } from "./ExprBlock";
import "./InputBlock.css";
@ -161,7 +161,8 @@ export function InputBlock({ state, setState, score, onCancel, typeInfo }: Input
i={i} setI={setI} />
</span>
</Input>
::<TypeBlock type={typeInfo.type} />
{/* ::<TypeBlock type={typeInfo.type} /> */}
::<TypeInfoBlock typeInfo={typeInfo} />
</>
}

View file

@ -4,7 +4,7 @@ import { EnvContext } from "../../context/EnvContext";
import { GlobalContext } from "../../context/GlobalContext";
import { type TypeInfoLet } from "../../eval/infer_type";
import { Input } from "../other/Input";
import { Type } from "../other/Type";
import { Type, TypeInfoBlock } from "../other/Type";
import { ExprBlock, type ExprBlockState, type State2Props } from "./ExprBlock";
import "./LetInBlock.css";
@ -50,7 +50,7 @@ function DeclColumns({state, setState, score, typeInfo}) {
onTextChange={name => setState(state => ({...state, name}))}
extraHandlers={{}}
/>
:: <Type type={typeInfo.value.type} />
:: <TypeInfoBlock typeInfo={typeInfo.value} />
</span>
<span className="keyword column">&nbsp;=&nbsp;</span>
<span className="column">

View file

@ -70,3 +70,30 @@
50% { opacity:0; }
100% { opacity:1; }
}
.typeSignature {
display: inline-block;
/* z-index: 1; */
position: relative;
}
.typeDebug {
display: none;
}
.typeSignature:hover > .typeDebug {
display: inline-block;
position: absolute;
white-space-collapse: preserve;
width: max-content;
background-color: #d2ebf1e0;
color: black;
font-family: var(--my-monospace-font);
padding: 4px;
z-index: 1000;
}
.editor:hover > .typeSignature {
display: inline-block;
}

View file

@ -1,7 +1,15 @@
import { getHumanReadableName, getSymbol, symbolDict, symbolDictIterator, symbolFunction, symbolList, symbolProduct, symbolSet, symbolSetIterator, symbolSum } from "dope2";
import { getHumanReadableName, getSymbol, prettySS, symbolDict, symbolDictIterator, symbolFunction, symbolList, symbolProduct, symbolSet, symbolSetIterator, symbolSum } from "dope2";
import "./Type.css";
import { ValueUnknown } from "./Value";
import type { TypeInfo } from "../../eval/infer_type";
export function TypeInfoBlock({typeInfo}: {typeInfo: TypeInfo}) {
return <span className="typeSignature gotDebug">
<div><Type type={typeInfo.type}/></div>
<span className="typeDebug">{prettySS(typeInfo.subs)}</span>
</span>;
}
export function Type({type}) {
if (type === undefined) {