import type { Category } from './Category' import type * as HKT from './HKT' import type { Profunctor } from './Profunctor' import { identity, pipe } from './function' import { tuple } from './tuple' export interface Strong extends Profunctor { readonly first: FirstFn readonly second: SecondFn } export interface FirstFn { (): ( pab: HKT.Kind ) => HKT.Kind } export interface SecondFn { (): ( pbc: HKT.Kind ) => HKT.Kind } export function splitF(S: Strong, 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, readonly [A, C], readonly [B, D] > => pipe(S.first()(pab), C.compose(S.second()(pcd))) } export function fanOutF(S: Strong, C: Category) { return ( pab: 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, A, readonly [B, C] > => pipe( C.id(), S.dimap(identity, (a) => tuple(a, a)), C.compose(splitF(S, C)(pab, pbc)) ) }