UNPKG

effect-ts-laws

Version:
41 lines 2.37 kB
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