<h4>Instance-view edges</h4>
<div class="legend-row"><span class="swatch swatch-edge-wrap"><span class="swatch-edge solid green"></span></span><span>Class defines this instance</span></div>
<div class="legend-row"><span class="swatch swatch-edge-wrap"><span class="swatch-edge dotted purple"></span></span><span>Instance context — points at a predicate node</span></div>
- <div class="legend-row"><span class="swatch swatch-edge-wrap"><span class="swatch-edge solid amber"></span></span><span>Instance needs a superclass instance (matched locally)</span></div>
- <div class="legend-row"><span class="swatch swatch-edge-wrap"><span class="swatch-edge dashed gray"></span></span><span>Needs a superclass instance (no local match)</span></div>
+ <div class="legend-row"><span class="swatch swatch-edge-wrap"><span class="swatch-edge solid amber"></span></span><span>Superclass constraint, satisfied by an instance in this project</span></div>
+ <div class="legend-row"><span class="swatch swatch-edge-wrap"><span class="swatch-edge dashed gray"></span></span><span>Superclass constraint, points at a predicate node (external or context)</span></div>
<div class="legend-row"><span class="swatch swatch-edge-wrap"><span class="swatch-edge solid violet"></span></span><span>Family → one of its type family instances</span></div>
<div class="legend-row"><span class="swatch swatch-edge-wrap"><span class="swatch-edge dotted teal"></span></span><span>Type family instance resolves to a class instance (chain)</span></div>
const reqLabel = 'superclass constraint';
if (matched.length === 0) {
- // No instance found in our data; link to the superclass class
- // node (which we have to draw in this branch) and mark it
- // external/unresolved.
- const scClsId = ensureClassNode(sc.seSuperclass);
+ // No instance was found in our data — but the original
+ // module typechecked, so the constraint must be discharged
+ // somewhere. Two cases:
+ //
+ // (a) The same predicate (class + arg shape) is also in
+ // this instance's context. ensurePredicateNode returns
+ // the existing id, and the focused instance gains a
+ // *second* incoming edge ("superclass constraint")
+ // alongside the "instance context" one already there.
+ //
+ // (b) Otherwise this is a constraint defined *outside* the
+ // project. A fresh predicate node is created with role
+ // 'extern' (rendered gray), meaning "an instance must
+ // exist somewhere outside this project".
+ //
+ // In both cases the edge label is just "superclass
+ // constraint"; the predicate node carries class + args.
+ const pid = ensurePredicateNode(
+ sc.seSuperclass, reqArgs, 'extern', inst.iiTyVars
+ );
els.push({ group: 'edges', data: {
- id: instId + '#sc#' + si + '#none',
+ id: instId + '#sc#' + si + '#extern',
source: instId,
- target: scClsId,
+ target: pid,
kind: 'needs-external',
- label: reqLabel + ' (no local match)',
+ label: reqLabel,
}});
} else {
// Local match(es) exist. Connect the focused instance directly
'font-family': 'ui-monospace, "SF Mono", Menlo, Consolas, monospace',
},
},
+ // 'extern' predicate — an unmatched superclass requirement that
+ // *isn't* in the instance context: an instance must exist, just
+ // not in this project. Greyed out to read as "external" /
+ // "unknown" at a glance.
+ {
+ selector: 'node[kind = "predicate"][role = "extern"]',
+ style: {
+ 'background-color': '#f3f4f6',
+ color: '#374151',
+ 'border-color': '#9ca3af',
+ 'border-style': 'dashed',
+ },
+ },
// Orphan instances get a red dashed border, but only when the
// global "Mark orphans" toggle is on. The toggle adds the
// `.show-orphan` class to every orphan node in the graph; we only