Skip to content
Dinko Srkoč edited this page May 10, 2011 · 4 revisions

According to Wikipedia, a monoid is "algebraic structure with a single associative binary operation and an identity element". Identity element is also knows as neutral element.

Monoids must follow the monoid laws (similar to monads):

  1. left identity

    identity ∘ x ≡ x

  2. right identity

    x ∘ identity ≡ x

  3. associativity

    (x ∘ y) ∘ z ≡ x ∘ (y ∘ z)

Here are some examples of monoids in real world:

Strings

Neutral element: empty string, ""

Binary operator: concatenation, +

The laws:

  1. assert "" + "foo" == "foo"
  2. assert "foo" + "" == "foo"
  3. assert ("foo" + "bar") + "baz" == "foo" + ("bar" + "baz")

Lists

Neutral element: empty list, []

Binary operator: append, +

The laws:

  1. assert [] + [1, 2] == [1, 2]
  2. assert [1, 2] + [] == [1, 2]
  3. assert ([1] + [2, 3]) + [4, 5] == [1] + ([2, 3] + [4, 5])

Numbers, addition

Neutral element: zero, 0

Binary operation: addition, +

The laws:

  1. assert 0 + 5 == 5
  2. assert 5 + 0 == 5
  3. assert (1 + 2) + 3 == 1 + (2 + 3)

Numbers, multiplication

Neutral element: one, 1

Binary operation: multiplication, *

The laws:

  1. assert 1 * 5 == 5
  2. assert 5 * 1 == 5
  3. assert (2 * 3) * 4 == 2 * (3 * 4)

Booleans, any

Neutral element: false, false

Binary operation: or, ||

The laws:

  1. assert false || true == true
  2. assert true || false == true
  3. assert (true || false) || true == true || (false || true)

Booleans, all

Neutral element: true, true

Binary operation: and, &&

The laws:

  1. assert true && false == false
  2. assert false && true == false
  3. assert (false && true) && false == false && (true && false)

Making your own monoid

Monadologie will automatically convert the common data types to monoids while using writer monad, but one can certainly make their own, if need arises.

To make a monoid one must, unsurprisingly, implement the Monoid interface. The implementation must follow the laws described above.

import hr.helix.monadologie.monads.Monoid

/**
 * Not a particularly clever monoid implementation.
 */
class MyMonoid implements Monoid {
    private value 

    private Monoid(val) { value = val }

    Monoid getIdentity() { new Monoid(null) }

    Monoid append(Monoid other) {
        if (value == null)
            return other
        if (other == null)
            return value

        new Monoid(value + other)
    }

    def get() { value }

    static create(val) { new Monoid(val) }
}

Clone this wiki locally