Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | 1x 1x 36x 36x 36x 36x 36x 36x 36x 36x 1x 4x 4x 4x 4x 4x 4x 4x 4x 4x 1x 22x 22x 22x 22x 22x 22x 22x 22x | import {Law} from '#law'
import type {Equivalence} from 'effect/Equivalence'
import fc from 'fast-check'
/**
* Test that a binary operation is associative.
* @category algebraic laws
*/
export const associativity = <A>(
{
f,
a,
equals,
}: {
f: (a: A, b: A) => A
a: fc.Arbitrary<A>
equals: Equivalence<A>
},
note = '(a ⊕ b) ⊕ c = a ⊕ (b ⊕ c)',
name = 'associativity',
) => Law(name, note, a, a, a)((a, b, c) => equals(f(f(a, b), c), f(a, f(b, c))))
/**
* Test the composition of two operations cancels each other.
* @category algebraic laws
*/
export const inverse = <A, B>(
{
f,
g,
a,
equals,
}: {
f: (a: A) => B
g: (b: B) => A
a: fc.Arbitrary<A>
equals: Equivalence<A>
},
note = 'g ⚬ f = id',
name = 'inverse',
) => Law(name, note, a)(a => equals(g(f(a)), a))
/**
* Test that a binary operation is symmetric.
* @category algebraic laws
*/
export const symmetry = <A, B>(
{
f,
a,
equals,
}: {
f: (left: A, right: A) => B
a: fc.Arbitrary<A>
equals: Equivalence<B>
},
note = 'f(a, b) = f(b, a)',
name = 'symmetry',
) =>
Law(name, note, a, a)((left, right) => equals(f(left, right), f(right, left)))
|