from tungsten:
A monoid is a set closed under an associative binary operation and having a unit element i in S such that for all a from S, Ia = aI = a.
from the Wiki:
In abstract algebra, a branch of mathematics, a monoid is an algebraic structure with a single associative binary operation and a single element.
so that your intuition is more or less correct.
You should keep in mind that it is not defined for a “custom set” in Haskell, but a type. The difference is small (because types of type theory are very similar to sets in set theory), but types for which you can define an instance of Monoid do not have to be types representing mathematical sets.
In other words: a type describes the set of all values of this type. Monoid is an “interface” that states that any type that claims to adhere to this interface must provide an identifier value, a binary operation combining two values of this type, and there are some equations that they must satisfy in order to all common Monoid operations work as intended (for example, summarizing the list of monoid values in total) and do not produce illogical / inconsistent results.
In addition, note that in order for the type to be an instance of the Monoid class, the existence of an identification element in this set (type) is required.
For example, natural numbers form a monoid when added (identity = 0 ):
0 + n = n n + 0 = n
as well as multiplication (identity = 1 ):
1 * n = n n * 1 = n
also lists the monoid form under ++ (identity = [] ):
[] ++ xs = xs xs ++ [] = xs
also functions of type a -> a form a monoid in composition (identity = id )
id . f = f f . id = f
therefore, it is important to keep in mind that Monoid does not apply to types that are sets, but about types if they are treated as sets, so to speak.
as an example of an invalid Monoid instance, consider:
import Data.Monoid newtype MyInt = MyInt Int deriving Show instance Monoid MyInt where mempty = MyInt 0 mappend (MyInt a) (MyInt b) = MyInt (a * b)
if you now try the mconcat list of MyInt values, you will always get MyInt 0 as the result, because the identifier value 0 and the binary operation * do not work well:
λ> mconcat [MyInt 1, MyInt 2] MyInt 0