Group

A group adds an invertibility property to the properties of the monoid, which means that for every element, a, from the set, S, on which the group is defined, there is an inverse element so that the result of the operation on both of them is an identity element.

Formalized in the code, it looks like the following:

trait Group[S] extends Monoid[S] {
def inverse(a: S): S
}

The ScalaCheck property for this new law looks similar to the properties we defined for semigroup and monoid:

def invertibility[S : Group : Arbitrary]: Prop =
forAll((a: S) => {
val m = implicitly[Group[S]]
m.op(a, m.inverse(a)) == m.identity && m.op(m.inverse(a), a) == m.identity
})

Like we did previously, we can define an overarching check that aggregates single properties:

def groupProp[S : Group: Arbitrary]: Prop = monoidProp[S] && invertibility[S]

By adding a commutative property to the group, we'll get an abelian group. The commutative property states that for any two input elements, the order of arguments does not matter. For a group to be abelian, it does not need to implement anything; all it needs to do is satisfy this additional property! 

We can extend our check definitions to incorporate this:

def commutativity[S : Group : Arbitrary]: Prop =
forAll((a: S, b: S) => {
val m = implicitly[Group[S]]
m.op(a, b) == m.op(b, a)
})

def abelianGroupProp[S : Group: Arbitrary]: Prop =
groupProp[S] && commutativity[S]

Again, we also define a single comprehensive property to check all of the laws of the abelian group at once.

One example of the abelian group is integer under addition. It can be implemented by extending the monoid we defined previously:

implicit val intAddition: Group[Int] = new Group[Int] {
override def identity: Int = 0
override def op(l: Int, r: Int): Int = l + r
override def inverse(a: Int): Int = identity - a
}

The properties we defined previously can help to ensure that this is indeed a valid abelian group implementation:

property("ints under addition form a group") = {
import Group.intAddition
groupProp[Int]
}

property("ints under addition form an abelian group") = {
import Group.intAddition
groupProp[Int]
}

We will leave the reader with the task of executing these properties to check that our implementation is correct.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.218.224.226