import { id } from "../../../fun/domains/id/state";
import { unit, Unit } from "../../../fun/domains/unit/state";
import { BasicUpdater, Updater } from "../../../fun/domains/updater/state";
import { BasicFun, Fun } from "../../../fun/state";
export type LeftValue = { value: a; kind: "l" };
export const LeftValue = {
Updaters: {
value: (_: BasicUpdater): Updater> =>
Updater((v) => ({ ...v, value: _(v.value) })),
},
};
export type RightValue = { value: b; kind: "r" };
export const RightValue = {
Updaters: {
value: (_: BasicUpdater): Updater> =>
Updater((v) => ({ ...v, value: _(v.value) })),
},
};
export type Sum = { value: a; kind: "l" } | { value: b; kind: "r" };
export type Either = Sum;
export type Option = Sum;
export const Sum = Object.assign(
() => ({
Default: {
left: Fun((_: a): Sum => ({ value: _, kind: "l" })),
right: Fun((_: b): Sum => ({ value: _, kind: "r" })),
},
Updaters: {
left: Fun(
(_: BasicUpdater): Updater> =>
Updater(Sum().Updaters.map2(_, id)),
),
right: Fun(
(_: BasicUpdater): Updater> =>
Updater(Sum().Updaters.map2(id, _)),
),
map2: (
l: BasicFun,
r: BasicFun,
): Fun, Sum> =>
Sum().Operations.fold>(
Fun(l).then(Sum().Default.left),
Fun(r).then(Sum().Default.right),
),
},
Operations: {
fold: (
l: BasicFun,
r: BasicFun,
): Fun, c> =>
Fun((_) => (_.kind == "l" ? l(_.value) : r(_.value))),
},
}),
{
Default: {
left: (_: a): Sum => ({ value: _, kind: "l" }),
right: (_: b): Sum => ({ value: _, kind: "r" }),
},
Updaters: {
left: (_: BasicUpdater): Updater> =>
Updater(Sum.Updaters.map2(_, id)),
right: (_: BasicUpdater): Updater> =>
Updater(Sum.Updaters.map2(id, _)),
map2: (
l: BasicFun,
r: BasicFun,
): Fun, Sum> =>
Sum.Operations.fold>(
Fun(l).then(Sum.Default.left),
Fun(r).then(Sum.Default.right),
),
},
Operations: {
fold: (
l: BasicFun,
r: BasicFun,
): Fun, c> =>
Fun((_) => (_.kind == "l" ? l(_.value) : r(_.value))),
ofOption: (
onNone: BasicFun,
): BasicFun