From the following example, I think it is correct to say that String
defines a monoid under the concatenation operation since it is an associative binary operation and String
happens to have an identity element which is an empty string ""
.
scala> ("" + "Jane") + "Doe" == "" + ("Jane" + "Doe")
res0: Boolean = true
From the various texts I have been reading on the subject lately, it seems that the correct use of the term monoid is that the monoid is actually a combination of both the type (in this case String
) and an instance of some monoid type which defines the operation and identity element.
For example, here is a theoretical Monoid
type and a concrete instance of it as seems to be commonly defined in various books/articles:-
trait Monoid[A] {
def op(a1: A, a2: A): A
def zero: A
}
val stringMonoid = new Monoid[String] {
def op(a1: String, a2: String) = a1 + a2
val zero = ""
}
I know that we do not need trait Monoid[A]
nor stringMonoid
to be defined in the core (Scala, or rather Java) library to support my REPL output and that the example is just a tool to understand the abstract concept of a monoid.
My issue (and I am very possibly thinking about it way too much) is the purist definition. I know that the underlying java.lang.String
(or rather StringBuilder
) already defines the associative operation, but I do not think that there is an explicit definition of the identity element (in this case just an empty string ""
) defined anywhere.
Question:-
Is String
a monoid under the concatenation operation implicitly, just because we happen to know that using an empty string ""
provides the identity? Or is it that an explicit definition of the identity element for a type is unnecessary for it to be classed as a monoid (under a particular associative binary operation).