-
Notifications
You must be signed in to change notification settings - Fork 2
Monoid
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):
-
left identity
identity ∘ x ≡ x
-
right identity
x ∘ identity ≡ x
-
associativity
(x ∘ y) ∘ z ≡ x ∘ (y ∘ z)
Here are some examples of monoids in real world:
Neutral element: empty string, ""
Binary operator: concatenation, +
The laws:
assert "" + "foo" == "foo"assert "foo" + "" == "foo"assert ("foo" + "bar") + "baz" == "foo" + ("bar" + "baz")
Neutral element: empty list, []
Binary operator: append, +
The laws:
assert [] + [1, 2] == [1, 2]assert [1, 2] + [] == [1, 2]assert ([1] + [2, 3]) + [4, 5] == [1] + ([2, 3] + [4, 5])
Neutral element: zero, 0
Binary operation: addition, +
The laws:
assert 0 + 5 == 5assert 5 + 0 == 5assert (1 + 2) + 3 == 1 + (2 + 3)
Neutral element: one, 1
Binary operation: multiplication, *
The laws:
assert 1 * 5 == 5assert 5 * 1 == 5assert (2 * 3) * 4 == 2 * (3 * 4)
Neutral element: false, false
Binary operation: or, ||
The laws:
assert false || true == trueassert true || false == trueassert (true || false) || true == true || (false || true)
Neutral element: true, true
Binary operation: and, &&
The laws:
assert true && false == falseassert false && true == falseassert (false && true) && false == false && (true && false)
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) }
}