// @flow import { HKT } from './HKT' import type { HKT2 } from './HKT' import type { Functor } from './Functor' import { compose } from './Fun' import { id } from './Identity' /* The Yoneda `Functor` `Yoneda f` is a `Functor` for any type constructor `f`. Implementation based on the purescript-free package (https://github.com/purescript/purescript-free) */ class IsYoneda {} export type YonedaV = (f: (a: A) => B) => HKT; export type Yoneda = HKT2; export type YonedaF = HKT; export function inj(a: YonedaV): Yoneda { return ((a: any): Yoneda) } export function prj(fa: Yoneda): YonedaV { return ((fa: any): YonedaV) } /* Run a computation of type `Yoneda f a`. */ export function runYoneda(y: Yoneda, f: (a: A) => B): HKT { return prj(y)(f) } /* Lift a value described by the `Functor` `f` to the `Functor` `Yoneda f`. */ export function liftYoneda(functor: Functor, fa: HKT): Yoneda { return inj(function (k: (a: A) => B): HKT { return functor.map(k, fa) }) } /* Lower a value of type `Yoneda f a` to the type constructor `f`. */ export function lowerYoneda(y: Yoneda): HKT { return runYoneda(y, id) } export function map(f: (a: A) => B, y: Yoneda): Yoneda { return inj(function (k: (b: B) => C): HKT { return runYoneda(y, compose(k, f)) }) } if (false) { // eslint-disable-line ({ map }: Functor) }