// Sum-type (also called: tagged union, disjoin union, variant type) // A Sum-type always has only two variants, called "left" and "right". // Sum-types of more variants (called Enums) can be constructed by nesting Sum-types. import { prodType } from "./types.js"; import { GenericType, Type } from "../primitives/types.js"; import { typedFnType } from "./types.js"; import { makeGeneric } from "../generics/generics.js"; import { sumType } from "./types.js"; export const newLeft = left => ({t: "L", v: left }); // 't': tag, 'v': value export const newRight = right => ({t: "R", v: right}); // signature: // sum-type -> (leftType -> resultType, rightType -> resultType) -> resultType export const match = sum => handlers => sum.t === "L" ? handlers.l(sum.v) : handlers.r(sum.v); export const ModuleSum = {l:[ // binary type constructor // Type -> Type -> Type ...typedFnType(sumType, fnType => fnType (Type) (fnType (Type) (Type) ), ), // a -> a | b ...typedFnType(newLeft, fnType => makeGeneric((a, b) => fnType (a) (sumType(a)(b)) ), GenericType), // b -> a | b ...typedFnType(newRight, fnType => makeGeneric((a, b) => fnType (b) (sumType(a)(b)) ), GenericType), // a | b -> (a -> c, b-> c) -> c ...typedFnType(match, fnType => makeGeneric((a, b, c) => fnType (sumType(a)(b)) (fnType (prodType (fnType(a)(c)) (fnType(b)(c)) ) (c) ) ), GenericType), ]};