UNPKG

effect-ts-laws

Version:
27 lines 1.96 kB
import { addLawSets, Law, lawTests } from '#law'; import { SemiApplicative as SE, } from '@effect/typeclass'; import { pipe } from 'effect'; import { unfoldGiven } from './given.js'; import { semiAlternativeLaws } from './SemiAlternative.js'; /** * Typeclass laws for `Alternative`. * @category typeclass laws */ export const alternativeLaws = (given, suffix) => pipe(buildLaws(`Alternative${suffix ?? ''}`, given), pipe(given, semiAlternativeLaws, addLawSets)); const buildLaws = (name, given) => { const unfolded = unfoldGiven(given), { F, equalsFa, fa } = unfolded, { coproduct, coproductAll } = F, isApplicative = 'productAll' in F && 'of' in F; return lawTests(name, Law('left identity', '∅ ⊕ fa = fa', fa)(fa => equalsFa(coproduct(fa, F.zero()), fa)), Law('right identity', 'fa ⊕ ∅ = fa', fa)(fa => equalsFa(coproduct(F.zero(), fa), fa)), Law('coproductAll zero', 'coproductAll([]) = ∅', fa)(() => equalsFa(coproductAll([]), F.zero())), ...(isApplicative ? buildApplicativeLaws(given) : [])); }; // Extra laws for alternatives that have an applicative instance. const buildApplicativeLaws = (given) => { const { F, equalsFb, fa, ab, fabOf } = unfoldGiven(given), { coproduct, map } = F; const Ap = F, ap = SE.ap(Ap), of = Ap.of, fab = fabOf(of); return [ Law('right absorption', 'ap(fab, ∅) = ∅', fab)(fab => equalsFb(ap(fab, F.zero()), F.zero())), Law('left distributivity', 'coproduct(fa₁, fa₂) ▹ map(ab) =' + ' coproduct(map(fa₁, ab), map(fa₂, ab))', fa, fa, ab)((fa1, fa2, ab) => equalsFb(pipe(coproduct(fa1, fa2), map(ab)), coproduct(map(fa1, ab), map(fa2, ab)))), Law('right distributivity', 'coproduct(fab₁, fab₂) ▹ ap(fa) =' + ' coproduct(ap(fab₁, fa), ap(fab₂, fa))', fa, fab, fab)((fa, fab1, fab2) => equalsFb(pipe(coproduct(fab1, fab2), ap(fa)), coproduct(ap(fab1, fa), ap(fab2, fa)))), ]; }; //# sourceMappingURL=Alternative.js.map