typelevel / algebra
1
package algebra.laws
2

3
import cats.kernel._
4
import cats.kernel.instances.option._
5

6
import org.typelevel.discipline.Laws
7

8
import org.scalacheck.{Arbitrary, Prop}
9
import org.scalacheck.Prop._
10

11
object GroupLaws {
12 2
  def apply[A : Eq : Arbitrary]: GroupLaws[A] = new GroupLaws[A] {
13 2
    def Equ = Eq[A]
14 2
    def Arb = implicitly[Arbitrary[A]]
15
  }
16
}
17

18
trait GroupLaws[A] extends Laws {
19

20
  implicit def Equ: Eq[A]
21
  implicit def Arb: Arbitrary[A]
22

23
  // groups
24

25 2
  def semigroup(implicit A: Semigroup[A]): GroupProperties = new GroupProperties(
26 2
    name = "semigroup",
27 2
    parents = Nil,
28 2
    Rules.serializable(A),
29 2
    Rules.associativity(A.combine),
30 2
    Rules.repeat1("combineN")(A.combineN),
31 2
    Rules.repeat2("combineN", "|+|")(A.combineN)(A.combine),
32 2
    "combineAllOption" -> forAll { (xs: Vector[A]) =>
33 2
      A.combineAllOption(xs) ?== xs.reduceOption(A.combine)
34
    }
35
  )
36

37 2
  def band(implicit A: Band[A]): GroupProperties = new GroupProperties(
38 2
    name = "band",
39 2
    parents = List(semigroup),
40 2
    Rules.idempotence(A.combine),
41 2
    "isIdempotent" -> Semigroup.isIdempotent[A]
42
  )
43

44 2
  def commutativeSemigroup(implicit A: CommutativeSemigroup[A]): GroupProperties = new GroupProperties(
45 2
    name = "commutative semigroup",
46 2
    parents = List(semigroup),
47 2
    Rules.commutative(A.combine)
48
  )
49

50 2
  def semilattice(implicit A: Semilattice[A]): GroupProperties = new GroupProperties(
51 2
    name = "semilattice",
52 2
    parents = List(band, commutativeSemigroup)
53
  )
54

55 2
  def monoid(implicit A: Monoid[A]): GroupProperties = new GroupProperties(
56 2
    name = "monoid",
57 2
    parents = List(semigroup),
58 2
    Rules.leftIdentity(A.empty)(A.combine),
59 2
    Rules.rightIdentity(A.empty)(A.combine),
60 2
    Rules.repeat0("combineN", "id", A.empty)(A.combineN),
61 2
    Rules.collect0("combineAll", "id", A.empty)(A.combineAll),
62 2
    Rules.isId("isEmpty", A.empty)(A.isEmpty),
63 2
    "combineAll" -> forAll { (xs: Vector[A]) =>
64 2
      A.combineAll(xs) ?== (A.empty +: xs).reduce(A.combine)
65
    }
66
  )
67

68 2
  def commutativeMonoid(implicit A: CommutativeMonoid[A]): GroupProperties = new GroupProperties(
69 2
    name = "commutative monoid",
70 2
    parents = List(monoid, commutativeSemigroup)
71
  )
72

73 2
  def boundedSemilattice(implicit A: BoundedSemilattice[A]): GroupProperties = new GroupProperties(
74 2
    name = "boundedSemilattice",
75 2
    parents = List(commutativeMonoid, semilattice)
76
  )
77

78 2
  def group(implicit A: Group[A]): GroupProperties = new GroupProperties(
79 2
    name = "group",
80 2
    parents = List(monoid),
81 2
    Rules.leftInverse(A.empty)(A.combine)(A.inverse),
82 2
    Rules.rightInverse(A.empty)(A.combine)(A.inverse),
83 2
    Rules.consistentInverse("remove")(A.remove)(A.combine)(A.inverse)
84
  )
85

86 2
  def commutativeGroup(implicit A: CommutativeGroup[A]): GroupProperties = new GroupProperties(
87 2
    name = "commutative group",
88 2
    parents = List(group, commutativeMonoid)
89
  )
90

91
  // property classes
92

93
  class GroupProperties(
94
    val name: String,
95
    val parents: Seq[GroupProperties],
96
    val props: (String, Prop)*
97
  ) extends RuleSet {
98 2
    val bases = Nil
99
  }
100
}

Read our documentation on viewing source code .

Loading