import type { Category } from './Category' import type { Either } from './Either' import type * as HKT from './HKT' import type { Profunctor } from './Profunctor' import { identity, pipe } from './function' export interface Choice extends Profunctor { readonly left: LeftFn readonly right: RightFn } export interface LeftFn { (): ( pab: HKT.Kind ) => HKT.Kind, Either> } export interface RightFn { (): ( pbc: HKT.Kind ) => HKT.Kind, Either> } export function splitF(P: Choice, C: Category) { return ( pab: HKT.Kind, pcd: HKT.Kind< F, TC, HKT.Intro, HKT.Intro, HKT.Intro, HKT.Intro, HKT.Intro, HKT.Intro, HKT.Intro, HKT.Intro, C, D > ): HKT.Kind< F, TC, HKT.Mix, HKT.Mix, HKT.Mix, HKT.Mix, HKT.Mix, HKT.Mix, HKT.Mix, HKT.Mix, Either, Either > => pipe(P.left()(pab), C.compose(P.right()(pcd))) } export function fanInF(P: Choice, C: Category) { return ( pac: HKT.Kind, pbc: HKT.Kind< F, TC, HKT.Intro, HKT.Intro, HKT.Intro, HKT.Intro, HKT.Intro, HKT.Intro, HKT.Intro, HKT.Intro, B, C > ): HKT.Kind< F, TC, HKT.Mix, HKT.Mix, HKT.Mix, HKT.Mix, HKT.Mix, HKT.Mix, HKT.Mix, HKT.Mix, Either, C > => pipe( splitF(P, C)(pac, pbc), C.compose( pipe( C.id(), P.dimap((cc: Either) => (cc._tag === 'Left' ? cc.left : cc.right), identity) ) ) ) }