dope2/compare/type.js
Joeri Exelmans 8eec5b9239 recursive types (and operations on them, like pretty-printing, comparison and unification) seem to be working.
big part of the code base still needs to be 'ported' to the updated type constructors.
2025-05-05 17:17:45 +02:00

38 lines
1.5 KiB
JavaScript

import { getParams, getSymbol } from "../type_constructor.js";
import { compareBools, compareSymbols } from "./primitives.js";
import { compareLists } from "./structures.js";
const __compareTypes = state => typeX => typeY => {
// tagX and tagY: just something unique & deterministic that can serve as JS map key
const tagX = state.nextTag++;
const tagY = state.nextTag++;
state.tagsX.add(tagX);
state.tagsY.add(tagY);
state.comparing.set(tagX, tagY);
return compareSymbols(getSymbol(typeX))(getSymbol(typeY))
|| compareLists
(paramOfX => paramOfY => {
const pX = paramOfX(tagX);
const pY = paramOfY(tagY);
return compareBools(state.tagsX.has(pX))(state.tagsY.has(pY))
|| (() => {
if (state.tagsX.has(pX)) {
// both sub-types have been visited already in an enclosing call
// if they were being compared in the same enclosing call, we assume they are equal!
// (we cannot compare them, that would result in endless recursion)
return compareSymbols(state.comparing.get(pX))(pY);
}
// none have been visited -> recursively compare
return __compareTypes(state)(pX)(pY);
})();
})
(getParams(typeX))
(getParams(typeY));
};
export const compareTypes = typeX => typeY => __compareTypes({
tagsX: new Set(),
tagsY: new Set(),
comparing: new Map(),
nextTag: 0,
})(typeX)(typeY);