I havenâ€™t worked out how to make the svg live on the haddocks yet, but numhask includes something like this, for its class structure, but where the boxes link to the haddocks of each class:

The functionality is published in dotparse. If thereâ€™s any interest, I could do the same for these flowcharts.

Very curious that back in the day the relation between Monad and Functor did not exist. I was aware that Applicative was discovered much later, but I had never suspected that Monad and Functor used to be totally unrelated!

If a monad is just a monoid in the category of endofunctors, then why these classes are totally isolated from each other?

Because `Monad`

doesnâ€™t represent all mathematical monads (just a very restricted subset) nor does `Monoid`

represent all mathematical monoids.

Sometimes I wish `Category`

from base is a bit more generalized:

```
{-# LANGUAGE TypeFamilies #-}
import Data.Kind (Constraint, Type)
import qualified GHC.Base (id, (.))
class Hask a; instance Hask (a :: Type)
-- Compatible with base category by default CategoryObj to all Types
class Category cat where
type family CategoryObj cat :: Type -> Constraint
type instance CategoryObj cat = Hask
id :: CategoryObj cat a => cat a a
(.) :: (CategoryObj cat a, CategoryObj cat b, CategoryObj cat c) => cat b c -> cat a b -> cat a c
class MyBizzaroObj a
data (:->) a b = (MyBizzaroObj a, MyBizzaroObj b) => a :-> b
instance Category (:->) where
type instance CategoryObj (:->) = MyBizzaroObj
id = undefined -- some bizzaro stuff
(.) = undefined
```

I vaguely recall index-core: Indexed Types is somewhat related.

I would say the reason is that for you to be able to have Monad related to Monoid, via â€śMonoid in the Category of Endofunctorsâ€ť youâ€™d have to have a different structure to the type class hierarchy. A Categorical one, which was not the original type class hierarchy path that Haskell took.

Indeed, however there are two ways of doing it (letâ€™s forget Applicative). The current one

```
class Functor m => Monad m where ...
```

This forces you to implement `fmap`

explicitely. Or something I which could be done

```
instance Monad m => Functor m where ...`
```

The first says a Monad needs to be a Functor (in anoher Monad implies being a Functor which could be written `Monad => Functor`

(the reverse of the actual notation). In other way, every Monad **has to** be a Functor.

The second is saying a Monad implies a Functor (`Monad => Functor`

agin), given any Monad I can make it a Functor instance (because I can implement `fmap`

in term of `>>=`

and `return`

).

In other words, every Monad **is** a Functor ( and I donâ€™t need to do anythig about it).

I remember at the time it to be annoying to have to define `fmap`

even though it was already done in the Monad instance.