## Group

If we define a binary operator $op$ on set $G$, which satisfied such properties

Closed, for any $a$ and $b$, has property $op(a,b) \in G$

Associativity, for any $a$ and $b$, has property $op(op(a, b), c) = op(a, op(b, c))$

Exist an identity element $e$ which for any $a$, has $op(e, a) = op(a, e) = a$

Exist inverse element, for any $a \in G$, has a inverse element $a^{-1}$ which $ op(a^{-1}, a) = op(a, a^{-1}) = e $

then we say $(G, op)$ is a group.

## Semigroup

If a binary operation and set combination $(G, op)$ just satisfy closure and associativity properties, then we call it is a *semigroup*.

## Monoid

If a group $(G, op)$ satisfies closure, associativity, and also exists an identity, then we call it is a *monoid*.

## Example

For examples, we can use Scale code to demonstrate these concepts.

```
trait SemiGroup[T] {
def plus(a : T, b : T) : T
}
// Int is a semigroup
object IntSemiGroup extends SemiGroup[Int] {
def plus(a : Int, b : Int) = a + b
}
trait Monoid[T] extends SemiGroup[T] {
def identity : T
}
// Int is also a Monoid
object IntMonoid extends Monoid[Int] {
def plus(a : Int, b : Int) = a + b
def identity = 0
}
```