@typed/fp
Version:
Data Structures and Resources for fp-ts
93 lines • 2.79 kB
JavaScript
import { left, match, right } from 'fp-ts/Either';
import { flow, identity, pipe } from 'fp-ts/function';
import { chain as chain_, doFx, map as map_ } from './Fx';
/**
* Create a lift function that will convert any F<A> into Fx<F<A>, A>
* @category Constructor
* @since 0.13.0
*/
export const liftFx = () => lift_;
function lift_(hkt) {
return {
[Symbol.iterator]: function* () {
const value = yield hkt;
return value;
},
};
}
export function getDo() {
const lift = liftFx();
return (f) => doFx(() => f(lift));
}
/**
* Using a ChainRec instance we can create a stack-safe interpreter for do-notation
* using Fx + generators.
*/
export function toMonad(M) {
return function fxToMonad(fx) {
return pipe(M.of(fx[Symbol.iterator]), M.map((f) => f()), M.chain((generator) => {
const result = generator.next();
if (result.done) {
return M.of(result.value);
}
return pipe(result.value, M.chain(M.chainRec((a) => {
const result = generator.next(a);
return result.done ? pipe(result.value, right, M.of) : pipe(result.value, M.map(left));
})));
}));
};
}
export function map() {
return map_;
}
export function chain() {
return chain_;
}
export function ap(M) {
const lift = liftFx();
const to = toMonad(M);
return (fa) => (fab) => pipe(fab, to, pipe(fa, to, M.ap), lift);
}
export function chainRec(M) {
return chainRec_(M);
}
function chainRec_(M) {
const to = toMonad(M);
const lift = liftFx();
return (f) => (a) => {
const fbm = pipe(f(a), to, M.chain(match(M.chainRec((a) => pipe(a, f, to)), M.of)));
return lift(fbm);
};
}
export function of(M) {
const lift = liftFx();
return (value) => lift(M.of(value));
}
export function ask(M) {
const lift = liftFx();
return () => lift(M.fromReader(identity));
}
export function useSome(M) {
const lift = liftFx();
const to = toMonad(M);
return (provided) => (fx) => pipe(fx, to, (x) => M.useSome(provided)(x), lift);
}
export function provideSome(M) {
const lift = liftFx();
const to = toMonad(M);
return (provided) => (fx) => pipe(fx, to, (x) => M.provideSome(provided)(x), lift);
}
export function useAll(M) {
const lift = liftFx();
const to = toMonad(M);
return (provided) => (fx) => pipe(fx, to, (x) => M.useAll(provided)(x), lift);
}
export function provideAll(M) {
const lift = liftFx();
const to = toMonad(M);
return (provided) => (fx) => pipe(fx, to, (x) => M.provideAll(provided)(x), lift);
}
export function fromNaturalTransformation(transformation) {
return flow(transformation, liftFx());
}
//# sourceMappingURL=FxT.js.map