37 lines
No EOL
1.3 KiB
JavaScript
37 lines
No EOL
1.3 KiB
JavaScript
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},
|
||
]};
|
||
}; |