import { makeGeneric } from "../generics/generics.js"; import { Type } from "../metacircular.js"; import { DefaultMap } from "../util.js"; import { typedFnType } from "./function.js"; const symbolProduct = Symbol("Product"); const productTypeRegistry = new DefaultMap(leftType => new DefaultMap(rightType => ({ symbol: symbolProduct, params: [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; export const ModuleProduct = {l: [ // binary type constructor // Type -> Type -> Type ...typedFnType(prodType, fnType => fnType (Type) (fnType (Type) (Type) ) ), // a -> b -> (a, b) ...typedFnType(constructor, fnType => makeGeneric((a, b) => fnType (a) (fnType (b) (prodType(a)(b)) ) )), // (a, b) -> a ...typedFnType(getLeft, fnType => makeGeneric((a, b) => fnType (prodType(a)(b)) (a) )), // (a, b) -> b ...typedFnType(getRight, fnType => makeGeneric((a, b) => fnType (prodType(a)(b)) (b) )), ]};