(This answer stole its definitions from https://stackoverflow.com/a/3870310/200266 and only tries to give a rough explanation. My knowledge of category theory is rather basic.)
In the generic case, saying that a monad is also a monoid is only valid, if you consider the functor (eg. T => Option[T]
) and not the values (eg. Some(3)
or None
).
As an example for a monoid over values, let’s have a look at List[T]
.
We have a binary operation • : S × S -> S:
def append[T](list1: List[T], list2: List[T]): List[T] = list1 append list2
and the empty list Nil
is obviously the identity element. There is no append
method in every monad, though, so the above cannot be generalised onto all monads. Let’s change the definition of the binary operation a bit.
Now, in the above case × can be seen as returning a tuple of the input values:
List[T] × List[T] => (List[T], List[T])
And our append
function receives this tuple as its input.
However, we may change the tupling operation × to ∘, now meaning functor composition.
(K => List[K]) ∘ (K => List[K]) => (K => List[List[K]])
And so, we’re looking for a function fulfilling μ : T ∘ T -> T or more specific
(K => List[List[K]]) => (K => List[K])
That operation is known in Scala as flatten
(join
in Haskell). The monoid’s identity element is the the monad constructor which has no generic name in Scala (return
in Haskell), but which exists for every monad. Eg. x => List(x)
.
To wrap things up, considering this and the other answers in this question, there are three possibilities for how a monad can be a monoid:
A) Every monad is also a monoid in the above sense under functor composition.
B) Every monad M[T]
has a monoid if there is also a monoid (with some binary operation ~+~
) for T: for {x <- ma; y <- mb} yield x ~+~ y
C) Some monads may have one or more specific monoids which differs from the one in B. For example List
’s append or Option
’s orElse
.