effect-ts-laws
Version:
effect-ts law testing using fast-check.
41 lines • 2.37 kB
JavaScript
import { option, unary, unaryToKind } from '#arbitrary';
import { addLawSets, Law, lawTests } from '#law';
import { Applicative as arrayApplicative } from '@effect/typeclass/data/Array';
import { Applicative as identityApplicative } from '@effect/typeclass/data/Identity';
import { Applicative as optionApplicative, Covariant as optionCovariant, Traversable as optionTraversable, } from '@effect/typeclass/data/Option';
import { Array as AR, flow, identity, Option as OP, pipe, } from 'effect';
import fc from 'fast-check';
import { composeApplicative } from '../../../compose.js';
import { withOuterOption } from './compose.js';
/**
* Typeclass laws for `Traversable`.
* @category typeclass laws
*/
export const traversableLaws = (given, suffix) => pipe(buildLaws(`Traversable${suffix ?? ''}`, given), addLawSets(buildLaws(...withOuterOption('Traversable', given, optionTraversable))));
const buildLaws = (name, { F, equalsA, equalsB, equalsC, getEquivalence, getArbitrary, a, b, c, }) => {
const fa = getArbitrary(a), [equalsFa, equalsFb, equalsFc] = [
getEquivalence(equalsA),
getEquivalence(equalsB),
getEquivalence(equalsC),
], [traverseIdentity, traverseG, traverseH, traverseGH] = [
F.traverse(identityApplicative),
F.traverse(optionApplicative),
F.traverse(arrayApplicative),
F.traverse(composeApplicative(optionApplicative, arrayApplicative)),
], mapG = optionCovariant.map, [ab, agb, bhc] = [
unary()(b),
pipe(b, unaryToKind()(option)),
pipe(c, unaryToKind()(fc.array)),
];
const equalsGHFc = pipe(equalsFc, AR.getEquivalence, OP.getEquivalence);
return lawTests(name, Law('identity', 'Id.traverse(id) = id', fa)(fa => equalsFa(pipe(fa, traverseIdentity(identity)), fa)), Law('composition', 'G.map(H.traverse(bhc)) ∘ G.traverse(agb)' +
' = GH.traverse(G.map(bhc) ∘ agb)', fa, agb, bhc)((fa, agb, bhc) => equalsGHFc(pipe(fa, traverseG(agb), mapG(traverseH(bhc))), pipe(fa, traverseGH(flow(agb, mapG(bhc)))))), ...('map' in F
? [
Law('map consistency', 'fa ▹ F.map(ab) = fa ▹ Id.traverse(ab)', fa, ab)((fa, ab) => {
const map = F.map;
return equalsFb(pipe(fa, map(ab)), pipe(fa, traverseIdentity(ab)));
}),
]
: []));
};
//# sourceMappingURL=Traversable.js.map