I\'ve read about monoid homomorphism from Monoid Morphisms, Products, and Coproducts and could not understand 100%.
The author says (emphasis original):
Datatype cannot be a monoid on its own. For a monoid, you need a data type T
and two more things:
|+|
, that takes two elements of type T
and produces an element of type T
T
, let's call it i
, such that for every element t
of type T
the following holds: t |+| i = i |+| t = t
Here are some examples of a monoid:
Monoid homomorphism
String concatenation monoid can be transformed into integer addition monoid by applying .length
to all its elements. Both those sets form a monoid. By the way, remember that we can't just say "set of integers forms a monoid"; we have to pick an associative operation and a corresponding identity element. If we take e.g. division as operation, we break the first rule (instead of producing an element of type integer, we might produce an element of type float/double).
Method length
allows us to go from a monoid (string concatenation) to another monoid (integer addition). If such operation also preserves monoid structure, it is considered to be a monoid homomorphism.
Preserving the structure means:
length(t1 |+| t2) = length(t1) |+| length(t2)
and
length(i) = i'
where t1
and t2
represent elements of the "source" monoid, i
is the identity of the "source" monoid, and i'
is the identity of the "destination" monoid. You can try it out yourself and see that length
indeed is a structure-preserving operation on a string concatenation monoid, while e.g. indexOf("a")
isn't.
Monoid isomorphism
As demonstrated, length
maps all strings to their corresponding integers and forms a monoid with addition as operation and zero as identity. But we can't go back - for every string, we can figure out its length, but given a length we can't reconstruct the "original" string. If we could, then the operation of "going forward" combined with the operation of "going back" would form a monoid isomorphism.
Isomorphism means being able to go back and forth without any loss of information. For example, as stated earlier, list forms a monoid under appending as operation and empty list as identity element. We could go from "list under appending" monoid to "vector under appending" monoid and back without any loss of information, which means that operations .toVector
and .toList
together form an isomorphism. Another example of an isomorphism, which Runar mentioned in his text, is String
⟷ List[Char]
.