Skip to content

Commit

Permalink
Omit *context* if it is not constrainted
Browse files Browse the repository at this point in the history
  • Loading branch information
davazp committed Apr 2, 2020
1 parent 2e27463 commit e4d3385
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 13 deletions.
20 changes: 14 additions & 6 deletions packages/delisp-core/src/type-utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { InvariantViolation } from "./invariant";
import { generateUniqueTVar } from "./type-generate";
import * as T from "./types";
import { flatMap, flatten, last, unique } from "./utils";
import { flatten, flatMap, last, unique } from "./utils";

export function isTVar(t: T.Type): t is T.Var {
return t.node.tag === "type-variable";
Expand All @@ -26,16 +26,24 @@ export function isFunctionType(t: T.Type): t is T.Application {
return isConstantApplicationType(t, "->");
}

export function typeChildren<A>(type: T.TypeF<A[]>): A[] {
export function countTypeOccurrences(variable: T.Var, type: T.Type): number {
return foldType(type, (t) => {
return t.node.tag === "type-variable" && t.node.name === variable.node.name
? 1
: typeChildren(t).reduce((x, y) => x + y, 0);
});
}

export function typeChildren<A>(type: T.TypeF<A>): A[] {
switch (type.node.tag) {
case "constant":
case "type-variable":
case "empty-row":
return [];
case "application":
return flatten([type.node.op, ...type.node.args]);
return [type.node.op, ...type.node.args];
case "row-extension":
return [...type.node.labelType, ...type.node.extends];
return [type.node.labelType, type.node.extends];
}
}

Expand Down Expand Up @@ -113,7 +121,7 @@ export function listTypeConstants(type: T.Type): T.Constant[] {
},
},
]
: typeChildren(t);
: flatten(typeChildren(t));
});
}

Expand All @@ -122,7 +130,7 @@ export function listTypeVariables(type: T.Type): string[] {
return foldType(type, (t) => {
return t.node.tag === "type-variable"
? [t.node.name]
: unique(typeChildren(t));
: unique(flatten(typeChildren(t)));
});
}

Expand Down
36 changes: 29 additions & 7 deletions packages/liphe/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,16 +154,30 @@ export const FunctionExplorer: React.FC<{ fn: Delisp.SFunction<Typed> }> = ({
}
const type = Delisp.decomposeFunctionType(selfType);

const [, ...args] = fn.node.lambdaList.positionalArguments;
const [contextType, ...argsTypes] = type.args;

const isUnconstraintContext =
Delisp.isTVar(contextType) &&
Delisp.countTypeOccurrences(contextType, selfType) === 1;

return (
<div className={styles.function}>
<span className={styles.functionLabel}>λ</span>

{isUnconstraintContext ? null : (
<div>
<strong>*context*</strong> -
<TypeExplorer type={contextType} />
</div>
)}

<ul className={styles.functionArguments}>
{fn.node.lambdaList.positionalArguments.map((arg, argPosition) => {
{args.map((arg, argPosition) => {
return (
<li key={arg.name}>
<IdentifierExplorer identifier={arg} /> -
<TypeExplorer type={type.args[argPosition]} />
<TypeExplorer type={argsTypes[argPosition]} />
</li>
);
})}
Expand Down Expand Up @@ -206,17 +220,25 @@ export const IdentifierExplorer: React.FC<{
};

export default function Homepage() {
const module = Delisp.macroexpandModule(
Delisp.readModule(`
(lambda (x1 x2) {:x (+ x1 x2) :y 20 :z {:name "david"} :callback (lambda () 3)})
`)
);
const [code, setCode] = useState(`
(lambda (x)
(+ *context* x)
)`);

const module = Delisp.macroexpandModule(Delisp.readModule(code));

const { typedModule } = Delisp.inferModule(module);

return (
<div>
<PageLayout>
<textarea
value={code}
onChange={(event) => {
setCode(event.target.value);
}}
/>

<ModuleExplorer module={typedModule} />
</PageLayout>
</div>
Expand Down

0 comments on commit e4d3385

Please sign in to comment.