effect-ts-folds
Version:
Recursion schemes for effect-ts.
28 lines • 2.97 kB
JavaScript
import { extract, fix, unfix } from '#fix';
import { fanout, square, squareMapFirst, traverseCovariant } from '#util';
import { Array, flow, Function, pipe, Tuple } from 'effect';
import { Law, LawSet } from 'effect-ts-laws';
import { algebraToCVAlgebra, cata, histo, para, zygo } from './schemes.js';
export const cataLaws = (F, { equalsF, equalsA, fixed, φ }) => {
const unfixed = fixed.map(unfix);
return LawSet()('catamorphism', Law('identity', 'cata(fix) = id', fixed)(fixed => equalsF(pipe(fixed, cata(F)(fix)), fixed)), Law('cancellation', 'cata(φ) ∘ fix = φ ∘ map(cata(φ))', unfixed, φ)((unfixed, φ) => equalsA(pipe(unfixed, fix, cata(F)(φ)), pipe(unfixed, traverseCovariant(F).map(cata(F)(φ)), φ))), Law('standalone cata consistency', 'cata(φ) = standaloneCata(φ)', fixed, φ)((fixed, φ) => equalsA(pipe(fixed, cata(F)(φ)), pipe(fixed, standaloneCata(F)(φ)))));
};
export const paraLaws = (F, { fixed, equalsA, equalsB, φ, rAlgebra }) => {
return LawSet()('paramorphism', Law('cata consistency', 'cata(φ) = para(φ ∘ F.map(Tuple.getSecond))', fixed, φ)((fixed, φ) => equalsA(pipe(fixed, cata(F)(φ)), pipe(fixed, paraBasedCata(F)(φ)))), Law('standalone para consistency', 'para(φ) = standalonePara(φ)', fixed, rAlgebra)((fixed, φ) => Array.getEquivalence(equalsB)(pipe(fixed, para(F)(φ)), pipe(fixed, standalonePara(F)(φ)))));
};
export const zygoLaws = (F, { fixed, equalsF, rAlgebra }) => {
return LawSet()('zygomorphism', Law('para consistency', 'para(φ) = zygo(φ ∘ F.map(Tuple.swap), fix)', fixed, rAlgebra)((fixed, φ) => pipe(fixed, fanout(para(F)(φ), zygoBasedPara(F)(φ)), Function.tupled(Array.getEquivalence(equalsF)))));
};
export const histoLaws = (F, { fixed, equalsA, cvAlgebra, φ }) => {
return LawSet()('histomorphism', Law('standalone histo consistency', 'histo(φ) = standaloneHisto(φ)', fixed, cvAlgebra)((fixed, φ) => Array.getEquivalence(equalsA)(pipe(fixed, histo(F)(φ)), pipe(fixed, standaloneHisto(F)(φ)))), Law('cata consistency', 'cata(φ) = histo(φ ∘ F.map(Cofree.extract))', fixed, φ)((fixed, φ) => equalsA(pipe(fixed, cata(F)(φ)), pipe(fixed, histoBasedCata(F)(φ)))));
};
const standaloneCata = F => φ => fixed => pipe(fixed, unfix, traverseCovariant(F).map(standaloneCata(F)(φ)), φ);
export const standalonePara = (F) => (φ) => (fixed) => pipe(fixed, unfix, traverseCovariant(F).map(flow(square, pipe(φ, standalonePara(F), (Tuple.mapSecond)))), φ);
const paraBasedCata = F => φ => para(F)(flow(traverseCovariant(F).map(Tuple.getSecond), φ));
export const histoBasedCata = (F) => (alg) => pipe(alg, algebraToCVAlgebra(F), histo(F));
export const zygoBasedPara = (F) => (φ) => zygo(F)(flow(traverseCovariant(F).map(Tuple.swap), φ), fix);
export const standaloneHisto = (F) => (φ) => {
const run = (fixed) => pipe(fixed, (unfix), traverseCovariant(F).map(run), squareMapFirst(φ));
return flow(run, extract);
};
//# sourceMappingURL=laws.js.map