I wanted to implement a Custom Datatype named ComplexNumber like this:
data ComplexNumber a = C (a,a)
Now I wanted to implement the Monoid Variable and define the binary mempty Element and the mappend like this:
instance Num a => Monoid (ComplexNumber a) where
mempty = C (0,0)
mappend = (C (a1, b1)) (C (a2, b2)) = C (a1 + a2, b1 + b2)
but this didn't work out, so tried to figure out why and came across Semigroup (which I still dont really understand) and came to a soloution that atleast compiles and seems to work with this:
instance Num a => Semigroup (ComplexNumber a) where
(C (a1, b1)) <> (C (a2,b2)) = C (a1 + a2, b1 + b2)
instance Num a => Monoid (ComplexNumber a) where
mempty = C (0,0)
The funny thing is, when i remove the implementation of Semigroup the programm doesn't compile anymore and gives me following error:
* Could not deduce (Semigroup (ComplexNumber a))
arising from the superclasses of an instance declaration
from the context: Num a
bound by the instance declaration at Aufgabe_10.hs:9:10-42
* In the instance declaration for `Monoid (ComplexNumber a)'
|
9 | instance Num a => Monoid (ComplexNumber a) where
|
Why is that i can compile those two sections together, but when i remove the semigroup an error occurs ? And what in particular is this Semigroup thing
Semigroupis just the class of all types that have an implementation of the<>operation, in a way so that it's associative (i.e. thata<>(b<>c) ≡ (a<>b)<>c, which does hold true for your complex numbers if we disregard small floating-point deviations).Monoidis the class of of semigroups which additionally have a neutral elementmempty, i.e. an element that always fulfillsmempty <> a ≡ a <> mempty ≡ a(also true for complex numbers with addition and zero).This would be a nonsensical requirement for a type that doesn't even have the
<>operation, i.e. that doesn't have aSemigroupinstance. This is expressed bySemigroupbeing a superclass ofMonoid, and thus it's impossible to have a type which is an instance ofMonoidbut not ofSemigroup.Historically,
SemigroupandMonoidwere separate classes, with the olderMonoidshipping its ownmappendoperation that is the equivalent to the modern<>. Some older books / tutorials are still based on this old class hierarchy.But because there are a bunch of types that are only semigroups, but not monoids, the class hierarchy was changed.