dope2/structures/sum.js

57 lines
1.4 KiB
JavaScript

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 constructorLeft = left => ({variant: "L", value: left });
export const constructorRight = right => ({variant: "R", value: right});
// signature:
// sum-type -> (leftType -> resultType, rightType -> resultType) -> resultType
export const match = sum => handlers => sum.variant === "L"
? handlers.left(sum.value)
: handlers.right(sum.value);
export const ModuleSum = {l:[
// binary type constructor
// Type -> Type -> Type
...typedFnType(sumType, fnType =>
fnType
(Type)
(fnType
(Type)
(Type)
),
),
// a -> a | b
...typedFnType(constructorLeft, fnType =>
makeGeneric((a, b) =>
fnType
(a)
(sumType(a)(b))
), GenericType),
// b -> a | b
...typedFnType(constructorRight, 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),
]};