import type { FunctorMin } from './Functor' import { identity } from './function' import { Functor } from './Functor' import * as HKT from './HKT' export interface Profunctor extends Functor { readonly dimap_: DimapFn_ readonly dimap: DimapFn readonly lmap_: LMapFn_ readonly lmap: LMapFn } export type ProfunctorMin = FunctorMin & ( | { readonly dimap_: DimapFn_ } | { readonly lmap_: LMapFn_ } | { readonly dimap_: DimapFn_, readonly lmap_: LMapFn_ } ) export function Profunctor(F: ProfunctorMin): Profunctor { let dimap_: DimapFn_ let lmap_: LMapFn_ if ('dimap_' in F) { dimap_ = F.dimap_ } else { dimap_ = (fa, f, g) => F.map_(F.lmap_(fa, f), g) } if ('lmap_' in F) { lmap_ = F.lmap_ } else { lmap_ = (fa, f) => F.dimap_(fa, f, identity) } return HKT.instance>({ ...Functor(F), dimap_, dimap: (f, g) => (fa) => dimap_(fa, f, g), lmap_, lmap: (f) => (fa) => lmap_(fa, f) }) } export interface DimapFn_ { ( fa: HKT.Kind, f: (r: R) => U, g: (A: A) => B ): HKT.Kind } export interface DimapFn { (f: (r: R) => U, g: (a: A) => B): ( fa: HKT.Kind ) => HKT.Kind } export interface LMapFn_ { ( fa: HKT.Kind, f: (r: R) => U ): HKT.Kind } export interface LMapFn { (f: (r: R) => U): ( fa: HKT.Kind ) => HKT.Kind }