import { inspect } from 'node:util'; import { symbolFunction, symbolList, symbolProduct, symbolSet, symbolSum } from '../structures/types.js'; import { mapRecursiveStructure } from './util.js'; export function pretty(obj) { return inspect(obj, { colors: true, depth: null, breakLength: 120 }); } // Pretty print type export const prettyT = type => { return mapRecursiveStructure(([type, m, seen], map) => { if (typeof type === "symbol") { return type.description; } if (!m.has(type)) { m.add(type); // next time we encounter this type, we'll only render a placeholder const params = type.params.map(p => map([p(type), m, seen])()); // if while visiting the children, we encountered ourselves, add annotation: const annot = seen.has(type) ? seen.get(type) : ``; return renderType(type.symbol, annot, params); } else { if (!seen.has(type)) { seen.set(type, `#${seen.size}`); } return seen.get(type); } })([type, new Set(), new Map()])(); }; const renderType = (symbol, annot, params) => { return { [symbolList] : `${annot}[${params[0]}]`, [symbolSet] : `${annot}{${params[0]}}`, [symbolFunction]: `${annot}(${params[0]} -> ${params[1]})`, [symbolSum] : `${annot}(${params[0]} + ${params[1]})`, [symbolProduct] : `${annot}(${params[0]} ⨯ ${params[1]})`, }[symbol] || symbol.description; }; export const prettyGenT = genericType => { return `∀${[...genericType.typeVars].map(prettyT).sort((a, b) => a.localeCompare(b)).join(",")}: ${prettyT(genericType.type)}`; };