import { fnType } from "../metacircular.js"; import { Function, Type } from "../metacircular.js"; import { DefaultMap } from "../util.js"; const productTypeRegistry = new DefaultMap(leftType => new DefaultMap(rightType => ({ operator: "product", leftType, rightType }))); // type constructor export const prodType = (leftType, rightType) => productTypeRegistry.getdefault(leftType, true).getdefault(rightType, true); // In JS, all products are encoded in the same way: const constructor = left => right => ({left, right}); const getLeft = product => product.left; const getRight = product => product.right; // Given two types A and B, create the type (A × B). export const makeProductType = (leftType, rightType) => { const pType = prodType(leftType, rightType); const leftFnType = fnType({in: pType, out: leftType}); const rightFnType = fnType({in: pType, out: rightType}); const constructorBoundType = fnType({in: rightType, out: pType}); const constructorType = fnType({in: leftType , out: constructorBoundType}); return {l:[ {i: pType, t: Type}, {i: getLeft , t: leftFnType}, {i: getRight , t: rightFnType}, {i: leftFnType , t: Function}, {i: rightFnType, t: Function}, {i: constructor , t: constructorType}, {i: constructorType , t: Function}, {i: constructorBoundType, t: Function}, ]}; };