export interface Both { readonly _tag: 'Both' readonly left: E readonly right: A } export interface Left { readonly _tag: 'Left' readonly left: E } export interface Right { readonly _tag: 'Right' readonly right: A } export type These = Left | Right | Both export function Left(e: E): These { return { _tag: 'Left', left: e } } export function Right(a: A): These { return { _tag: 'Right', right: a } } export function Both(e: E, a: A): These { return { _tag: 'Both', left: e, right: a } } export function match_( fa: These, onLeft: (e: E) => B, onRight: (a: A) => C, onBoth: (e: E, a: A) => D ): B | C | D { switch (fa._tag) { case 'Left': return onLeft(fa.left) case 'Right': return onRight(fa.right) case 'Both': return onBoth(fa.left, fa.right) } } export function match( onLeft: (e: E) => B, onRight: (a: A) => C, onBoth: (e: E, a: A) => D ): (fa: These) => B | C | D { return (fa) => match_(fa, onLeft, onRight, onBoth) }