typelevel / algebra
 1 ```package algebra.laws ``` 2 3 ```import cats.kernel._ ``` 4 ```import org.scalacheck.Prop ``` 5 ```import org.scalacheck.Prop._ ``` 6 ```import org.scalacheck.{Arbitrary, Prop} ``` 7 ```import cats.kernel.instances.boolean._ ``` 8 9 ```object Rules { ``` 10 11 ``` // Comparison operators for testing are supplied by CheckEqOps and ``` 12 ``` // CheckOrderOps in package.scala. They are: ``` 13 ``` // ``` 14 ``` // ?== Ensure that x equals y ``` 15 ``` // ?!= Ensure that x does not equal y ``` 16 ``` // ?< Ensure that x < y ``` 17 ``` // ?<= Ensure that x <= y ``` 18 ``` // ?> Ensure that x > y ``` 19 ``` // ?>= Ensure that x >= y ``` 20 ``` // ``` 21 ``` // The reason to prefer these operators is that when tests fail, we ``` 22 ``` // will get more detaild output about what the failing values were ``` 23 ``` // (in addition to the input values generated by ScalaCheck). ``` 24 25 ``` def associativity[A: Arbitrary: Eq](f: (A, A) => A): (String, Prop) = ``` 26 3 ``` "associativity" -> forAll { (x: A, y: A, z: A) => ``` 27 3 ``` f(f(x, y), z) ?== f(x, f(y, z)) ``` 28 ``` } ``` 29 30 ``` def leftIdentity[A: Arbitrary: Eq](id: A)(f: (A, A) => A): (String, Prop) = ``` 31 3 ``` "leftIdentity" -> forAll { (x: A) => ``` 32 3 ``` f(id, x) ?== x ``` 33 ``` } ``` 34 35 ``` def rightIdentity[A: Arbitrary: Eq](id: A)(f: (A, A) => A): (String, Prop) = ``` 36 3 ``` "rightIdentity" -> forAll { (x: A) => ``` 37 3 ``` f(x, id) ?== x ``` 38 ``` } ``` 39 40 ``` def leftInverse[A: Arbitrary: Eq](id: A)(f: (A, A) => A)(inv: A => A): (String, Prop) = ``` 41 3 ``` "left inverse" -> forAll { (x: A) => ``` 42 3 ``` id ?== f(inv(x), x) ``` 43 ``` } ``` 44 45 ``` def rightInverse[A: Arbitrary: Eq](id: A)(f: (A, A) => A)(inv: A => A): (String, Prop) = ``` 46 3 ``` "right inverse" -> forAll { (x: A) => ``` 47 3 ``` id ?== f(x, inv(x)) ``` 48 ``` } ``` 49 50 ``` def commutative[A: Arbitrary: Eq](f: (A, A) => A): (String, Prop) = ``` 51 3 ``` "commutative" -> forAll { (x: A, y: A) => ``` 52 3 ``` f(x, y) ?== f(y, x) ``` 53 ``` } ``` 54 55 ``` def idempotence[A: Arbitrary: Eq](f: (A, A) => A): (String, Prop) = ``` 56 3 ``` "idempotence" -> forAll { (x: A) => ``` 57 3 ``` f(x, x) ?== x ``` 58 ``` } ``` 59 60 ``` def consistentInverse[A: Arbitrary: Eq](name: String)(m: (A, A) => A)(f: (A, A) => A)(inv: A => A): (String, Prop) = ``` 61 3 ``` s"consistent \$name" -> forAll { (x: A, y: A) => ``` 62 3 ``` m(x, y) ?== f(x, inv(y)) ``` 63 ``` } ``` 64 65 ``` def repeat0[A: Arbitrary: Eq](name: String, sym: String, id: A)(r: (A, Int) => A): (String, Prop) = ``` 66 3 ``` s"\$name(a, 0) == \$sym" -> forAll { (a: A) => ``` 67 3 ``` r(a, 0) ?== id ``` 68 ``` } ``` 69 70 ``` def repeat1[A: Arbitrary: Eq](name: String)(r: (A, Int) => A): (String, Prop) = ``` 71 3 ``` s"\$name(a, 1) == a" -> forAll { (a: A) => ``` 72 3 ``` r(a, 1) ?== a ``` 73 ``` } ``` 74 75 ``` def repeat2[A: Arbitrary: Eq](name: String, sym: String)(r: (A, Int) => A)(f: (A, A) => A): (String, Prop) = ``` 76 3 ``` s"\$name(a, 2) == a \$sym a" -> forAll { (a: A) => ``` 77 3 ``` r(a, 2) ?== f(a, a) ``` 78 ``` } ``` 79 80 ``` def collect0[A: Arbitrary: Eq](name: String, sym: String, id: A)(c: Seq[A] => A): (String, Prop) = ``` 81 3 ``` s"\$name(Nil) == \$sym" -> forAll { (a: A) => ``` 82 3 ``` c(Nil) ?== id ``` 83 ``` } ``` 84 85 ``` def isId[A: Arbitrary: Eq](name: String, id: A)(p: A => Boolean): (String, Prop) = ``` 86 3 ``` name -> forAll { (x: A) => ``` 87 3 ``` Eq.eqv(x, id) ?== p(x) ``` 88 ``` } ``` 89 90 ``` def distributive[A: Arbitrary: Eq](a: (A, A) => A)(m: (A, A) => A): (String, Prop) = ``` 91 3 ``` "distributive" -> forAll { (x: A, y: A, z: A) => ``` 92 3 ``` (m(x, a(y, z)) ?== a(m(x, y), m(x, z))) && ``` 93 3 ``` (m(a(x, y), z) ?== a(m(x, z), m(y, z))) ``` 94 ``` } ``` 95 96 ``` // ugly platform-specific code follows ``` 97 98 ``` def serializable[M](m: M): (String, Prop) = ``` 99 3 ``` "serializable" -> (if (IsSerializable()) { ``` 100 3 ``` Prop(_ => Result(status = Proof)) ``` 101 ``` } else { ``` 102 0 ``` Prop(_ => IsSerializable.testSerialization(m)) ``` 103 ``` }) ``` 104 ```} ```

Read our documentation on viewing source code .