In the base documentation, one can read that Endo a
is “The monoid of endomorphisms under composition.”
I know what an endomorphism is, but I don’t understand precisely what Endo
represents.
My guess is that if the constraint Semigroup a
is satisfied, then Endo a
is a morphism of semigroups, if Monoid a
is satisfied, then it’s a morphism of monoids. The same should apply for any algebraic structures, even if they are not part of base
like Group
for example.
However, the more I think about it, the more I feel this is wrong. Suppose, for instance, that I’m interested in automorphisms. Then, following the Endo
style, I would write something like
newtype Auto x = Auto {appAuto :: x -> x}
But if I do something like this, I will not be able to provide a Group
instance for Auto x
. So this is bad. Another idea is to write
data Auto x = Auto {appAuto :: Endo x, appInv :: Dual (Endo x)}
Now I will be able to show that Auto x
is a group, and it looks like I should be happy. But should I ? I feel like all of this should be defined using classes instead of types.
So here are my questions :
- Did I understand correctly what
Endo
is supposed to do ? - If yes, is it considered a good practice in Haskell to use
newtype
instead of trying to define a class in such cases ?