export interface Semiring {
readonly add_: (x: A, y: A) => A
readonly add: (y: A) => (x: A) => A
readonly mul_: (x: A, y: A) => A
readonly mul: (y: A) => (x: A) => A
readonly zero: A
readonly one: A
}
export type SemiringMin = {
readonly add_: (x: A, y: A) => A
readonly mul_: (x: A, y: A) => A
readonly zero: A
readonly one: A
}
export function Semiring(S: SemiringMin): Semiring {
return {
...S,
add: (y) => (x) => S.add_(x, y),
mul: (y) => (x) => S.mul_(x, y),
}
}
export const getFunctionSemiring = (S: Semiring): Semiring<(a: A) => B> => ({
zero: () => S.zero,
one: () => S.one,
add: (f) => (g) => (x) => S.add_(f(x), g(x)),
mul: (f) => (g) => (x) => S.mul_(f(x), g(x)),
add_: (f, g) => (x) => S.add_(f(x), g(x)),
mul_: (f, g) => (x) => S.mul_(f(x), g(x))
})