// @flow import type { HKT2 } from './HKT' import type { Monad } from './Monad' import { HKT } from './HKT' import { compose } from './Fun' import { id } from './Identity' class IsReader {} export type ReaderV = (e: E) => A; export type Reader = HKT2; export function inj(a: ReaderV): Reader { return ((a: any): Reader) } export function prj(fa: Reader): ReaderV { return ((fa: any): ReaderV) } export function runReader(r: Reader, e: E): A { return prj(r)(e) } // reads the current context export function ask(): Reader { return inj(id) } export const asks = inj // changes the value of the local context during the execution of the action `fa` export function local(f: (e: E) => E, fa: Reader): Reader { return inj((e) => runReader(fa, f(e))) } export function map(f: (a: A) => B, fa: Reader): Reader { return inj(compose(f, prj(fa))) } export function ap(fab: Reader B>, fa: Reader): Reader { return chain((f) => map(f, fa), fab) // <= derived } export function of(a: A): Reader { return inj(() => a) } export function chain(f: (a: A) => Reader, fa: Reader): Reader { return inj((e) => prj(f(runReader(fa, e)))(e)) } if (false) { // eslint-disable-line ({ map, ap, of, chain }: Monad>) }