/** * StateEnvEither is a StateT of EnvEither. Resume-based altenative to * StateReaderTaskEither that support cancelation. * @since 0.9.2 */ import { Applicative4 } from 'fp-ts/Applicative' import { Apply4 } from 'fp-ts/Apply' import { Chain4 } from 'fp-ts/Chain' import { ChainRec4 } from 'fp-ts/ChainRec' import * as E from 'fp-ts/Either' import { FromEither4 } from 'fp-ts/FromEither' import * as FEi from 'fp-ts/FromEither' import { FromIO4 } from 'fp-ts/FromIO' import * as FIO from 'fp-ts/FromIO' import { FromReader4 } from 'fp-ts/FromReader' import * as FR from 'fp-ts/FromReader' import { FromState4 } from 'fp-ts/FromState' import * as FS from 'fp-ts/FromState' import { FromTask4 } from 'fp-ts/FromTask' import * as FT from 'fp-ts/FromTask' import { pipe } from 'fp-ts/function' import { Functor4 } from 'fp-ts/Functor' import { IO } from 'fp-ts/IO' import { Monad4 } from 'fp-ts/Monad' import { Pointed4 } from 'fp-ts/Pointed' import * as ST from 'fp-ts/StateT' import { Task } from 'fp-ts/Task' import { Env } from './Env' import * as EE from './EnvEither' import { FromEnv4 } from './FromEnv' import * as FE from './FromEnv' import { FromResume4 } from './FromResume' import * as FRe from './FromResume' import { MonadRec4 } from './MonadRec' import { Provide4, ProvideAll4, ProvideSome4, UseAll4, UseSome4 } from './Provide' import { Reader } from './Reader' import * as R from './Resume' /** * @since 0.9.2 * @category Model */ export interface StateEnvEither { (state: S): EE.EnvEither } /** * @since 0.9.2 * @category Combinator */ export const ap = ST.ap(EE.Chain) /** * @since 0.9.2 * @category Combinator */ export const chain = ST.chain(EE.Chain) /** * @since 0.9.2 * @category Combinator */ export const evaluate = ST.evaluate(EE.Chain) /** * @since 0.9.2 * @category Combinator */ export const execute = ST.execute(EE.Chain) /** * @since 0.9.2 * @category Constructor */ export const fromEnvEither = ST.fromF(EE.Chain) /** * @since 0.9.2 * @category Constructor */ export const fromState = ST.fromState(EE.Pointed) /** * @since 0.9.2 * @category Combinator */ export const map = ST.map(EE.Functor) /** * @since 0.9.2 * @category Constructor */ export const of = ST.of(EE.Pointed) /** * @since 0.9.2 * @category URI */ export const URI = '@typed/fp/StateEnvEither' /** * @since 0.9.2 * @category URI */ export type URI = typeof URI declare module 'fp-ts/HKT' { export interface URItoKind4 { [URI]: StateEnvEither } } declare module './HKT' { export interface URItoVariance { [URI]: V & V } } /** * @since 0.9.2 * @category Instance */ export const Pointed: Pointed4 = { of, } /** * @since 0.9.2 * @category Instance */ export const Functor: Functor4 = { map, } /** * @since 0.9.2 * @category Instance */ export const Apply: Apply4 = { ...Functor, ap, } /** * @since 0.9.2 * @category Instance */ export const Applicative: Applicative4 = { ...Apply, ...Pointed, } /** * @since 0.9.2 * @category Instance */ export const Chain: Chain4 = { ...Functor, chain, } /** * @since 0.9.2 * @category Instance */ export const Monad: Monad4 = { ...Chain, ...Pointed, } /** * @since 0.9.2 * @category Combinator */ export const chainRec = (f: (a: A) => StateEnvEither>) => (value: A) => (s: S) => (r: R): R.Resume> => { let resume = f(value)(s)(r) while (R.isSync(resume)) { const either = resume.resume() if (E.isLeft(either)) { return R.of(either) } const result = either.right s = result[1] if (E.isRight(result[0])) { return R.of(E.right([result[0].right, s])) } resume = f(result[0].left)(s)(r) } return pipe( resume, R.chain((e) => E.isLeft(e) ? R.of(e) : pipe( e.right[0], E.matchW( (a) => chainRec(f)(a)(e.right[1])(r), (b) => R.of(E.right([b, e.right[1]])), ), ), ), ) } /** * @since 0.9.2 * @category Instance */ export const ChainRec: ChainRec4 = { chainRec, } /** * @since 0.9.2 * @category Instance */ export const MonadRec: MonadRec4 = { ...Monad, chainRec, } /** * @since 0.9.2 * @category Constructor */ export const fromEither = ( either: E.Either, ): StateEnvEither => fromEnvEither(EE.fromEither(either)) /** * @since 0.9.2 * @category Instance */ export const FromEither: FromEither4 = { fromEither, } /** * @since 0.9.2 * @category Constructor */ export const fromIO = ( io: IO, ): StateEnvEither => fromEnvEither(EE.fromIO(io)) /** * @since 0.9.2 * @category Instance */ export const FromIO: FromIO4 = { fromIO, } /** * @since 0.9.2 * @category Constructor */ export const fromTask = ( io: Task, ): StateEnvEither => fromEnvEither(EE.fromTask(io)) /** * @since 0.9.2 * @category Instance */ export const FromTask: FromTask4 = { ...FromIO, fromTask, } /** * @since 0.9.2 * @category Constructor */ export const fromResume = ( resume: R.Resume, ): StateEnvEither => fromEnvEither(EE.fromResume(resume)) /** * @since 0.9.2 * @category Instance */ export const FromResume: FromResume4 = { fromResume, } /** * @since 0.9.2 * @category Constructor */ export const fromEnv = (env: Env): StateEnvEither => fromEnvEither(EE.fromEnv(env)) /** * @since 0.9.2 * @category Instance */ export const FromEnv: FromEnv4 = { fromEnv, } /** * @since 0.9.2 * @category Instance */ export const FromState: FromState4 = { fromState, } /** * @since 0.9.2 * @category Constructor */ export const fromReader = ( reader: Reader, ): StateEnvEither => fromEnvEither(EE.fromReader(reader)) /** * @since 0.9.2 * @category Instance */ export const FromReader: FromReader4 = { fromReader } /** * @since 0.9.2 * @category Constructor */ export const ask = FR.ask(FromReader) /** * @since 0.9.2 * @category Constructor */ export const asks = FR.asks(FromReader) /** * @since 0.9.2 * @category Combinator */ export const chainReaderK = FR.chainReaderK(FromReader, Chain) /** * @since 0.9.2 * @category Constructor */ export const fromReaderK = FR.fromReaderK(FromReader) /** * @since 0.9.2 * @category Combinator */ export const chainFirstResumeK = FRe.chainFirstResumeK(FromResume, Chain) /** * @since 0.9.2 * @category Combinator */ export const chainResumeK = FRe.chainResumeK(FromResume, Chain) /** * @since 0.9.2 * @category Constructor */ export const fromResumeK = FRe.fromResumeK(FromResume) /** * @since 0.9.2 * @category Combinator */ export const chainEnvK = FE.chainEnvK(FromEnv, Chain) /** * @since 0.9.2 * @category Combinator */ export const chainFirstEnvK = FE.chainFirstEnvK(FromEnv, Chain) /** * @since 0.9.2 * @category Constructor */ export const fromEnvK = FE.fromEnvK(FromEnv) /** * @since 0.9.2 * @category Combinator */ export const chainFirstTaskK = FT.chainFirstTaskK(FromTask, Chain) /** * @since 0.9.2 * @category Combinator */ export const chainTaskK = FT.chainTaskK(FromTask, Chain) /** * @since 0.9.2 * @category Constructor */ export const fromTaskK = FT.fromTaskK(FromTask) /** * @since 0.9.2 * @category Combinator */ export const chainFirstIOK = FIO.chainFirstIOK(FromTask, Chain) /** * @since 0.9.2 * @category Combinator */ export const chainIOK = FIO.chainIOK(FromTask, Chain) /** * @since 0.9.2 * @category Constructor */ export const fromIOK = FIO.fromIOK(FromTask) /** * @since 0.9.2 * @category Combinator */ export const chainEitherK = FEi.chainEitherK(FromEither, Chain) /** * @since 0.9.2 * @category Combinator */ export const chainOptionK = FEi.chainOptionK(FromEither, Chain) /** * @since 0.9.2 * @category Combinator */ export const filterOrElse = FEi.filterOrElse(FromEither, Chain) /** * @since 0.9.2 * @category Constructor */ export const fromEitherK = FEi.fromEitherK(FromEither) /** * @since 0.9.2 * @category Constructor */ export const fromOption = FEi.fromOption(FromEither) /** * @since 0.9.2 * @category Constructor */ export const fromOptionK = FEi.fromOptionK(FromEither) /** * @since 0.9.2 * @category Constructor */ export const fromPredicate = FEi.fromPredicate(FromEither) /** * @since 0.9.2 * @category Combinator */ export const chainStateK = FS.chainStateK(FromState, Chain) /** * @since 0.9.2 * @category Constructor */ export const fromStateK = FS.fromStateK(FromState) /** * @since 0.9.2 * @category Constructor */ export const get = FS.get(FromState) /** * @since 0.9.2 * @category Constructor */ export const gets = FS.gets(FromState) /** * @since 0.9.2 * @category Combinator */ export const modify = FS.modify(FromState) /** * @since 0.9.2 * @category Combinator */ export const put = FS.put(FromState) /** * @since 0.9.2 * @category Combinator */ export const useSome = (provided: R1) => (srte: StateEnvEither): StateEnvEither => (s) => (r) => srte(s)({ ...r, ...provided }) /** * @since 0.9.2 * @category Combinator */ export const provideSome = (provided: R1) => (srte: StateEnvEither): StateEnvEither => (s) => (r) => srte(s)({ ...provided, ...r }) /** * @since 0.9.2 * @category Combinator */ export const useAll = (provided: R) => (srte: StateEnvEither): StateEnvEither => (s) => () => srte(s)(provided) /** * @since 0.9.2 * @category Combinator */ export const provideAll = (provided: R) => (srte: StateEnvEither): StateEnvEither => (s) => (r) => srte(s)({ ...provided, ...(r as {}) }) /** * @since 0.9.2 * @category Instance */ export const UseSome: UseSome4 = { useSome, } /** * @since 0.9.2 * @category Instance */ export const UseAll: UseAll4 = { useAll, } /** * @since 0.9.2 * @category Instance */ export const ProvideSome: ProvideSome4 = { provideSome, } /** * @since 0.9.2 * @category Instance */ export const ProvideAll: ProvideAll4 = { provideAll, } /** * @since 0.9.2 * @category Instance */ export const Provide: Provide4 = { useSome, useAll, provideSome, provideAll, }