/** * @since 0.24.0 */ import { dual } from "effect/Function" import type { Kind, TypeLambda } from "effect/HKT" import type { Invariant } from "./Invariant.js" /** * @category type class * @since 0.24.0 */ export interface Contravariant extends Invariant { readonly contramap: { (f: (b: B) => A): (self: Kind) => Kind (self: Kind, f: (b: B) => A): Kind } } /** * Composing two contravariant functors yields a Covariant functor. * * Returns a default binary `map` composition. * * @since 0.24.0 */ export const contramapComposition = ( F: Contravariant, G: Contravariant ) => ( self: Kind>, f: (a: A) => B ): Kind> => F.contramap(self, G.contramap(f)) /** * Returns a default `imap` implementation. * * @since 0.24.0 */ export const imap = ( contramap: ( self: Kind, f: (b: B) => A ) => Kind ): Invariant["imap"] => dual(3, (self, _, from) => contramap(self, from))