简体   繁体   中英

Haskell, implementing Monoids. What is Semigroup and why does it act so weird?

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

Semigroup is just the class of all types that have an implementation of the <> operation, in a way so that it's associative (ie that a<>(b<>c) ≡ (a<>b)<>c , which does hold true for your complex numbers if we disregard small floating-point deviations).

Monoid is the class of of semigroups which additionally have a neutral element mempty , ie an element that always fulfills mempty <> 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, ie that doesn't have a Semigroup instance. This is expressed by Semigroup being a superclass of Monoid , and thus it's impossible to have a type which is an instance of Monoid but not of Semigroup .

Historically, Semigroup and Monoid were separate classes, with the older Monoid shipping its own mappend operation 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.

A monoid [wiki] is a semigroup [wiki] with identity: it has an identity element e [wiki] for which the associative binary operation will x ⊕ e = e ⊕ x = x for all elements x in the set. Every monoid is thus a semigroup , since a semigroup is an algebraic structure with an associative binary operator for which the same properties thus hold as in a monoid, except that there is no need for an identity element e .

Since base-4.9.0.0 , a Semigroup class has been introduced, but then Semigroup and Monoid did not "live together". Since it does not make much sense to define a different binary operator for the Semigroup than for the Monoid instance (since that would likely introduce confusion), since base-4.11.0.0 , Semigroup is a superclass of Monoid . Indeed, Monoid is defined as [src] :

 class Semigroup a => Monoid a where # … 

This means that in order to make something an instance of Monoid , it has to be an instance of Semigroup as well. The mappend:: Monoid a => a -> a -> a will automatically link to the implementation of (<>):: Semigroup a => a -> a -> a and will, likely, eventually be removed.

You thus can no longer define an instance of Monoid without defining an instance of Semigroup . But you can "mechanically" create an instance from an old instance of Monoid , since you simply move the implementation of mappend from the Monoid instance to the instance for Semigroup .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM