Question

I am trying to reconcile the Categorical definition of Monad with the other general representations/definitions that I have seen in some other tutorials/books.

Below, I am (perhaps forcefully) trying to bring the two definitions close, please point out the mistakes and provide corrections, where ever required

So Starting with the definition of Monads

Monads are just monoids in the category of endofunctors.

and with a little understanding of endofunctors, I assume a Monad can be written as

((a->b)->Ma->Mb)->((b->c)->Mb->Mc) 

The 'Type' of LHS (Left hand side) is Mb, and type of RHS is Mc, so I suppose I can write it as below

Mb-> (b->c)-> Mc, **which is how we define bind**

And here is how I see Monads in the category of endofuctors (which themselves are in Category C, with 'types' as objects)

Monad Visually.

Does any of this makes sense?

Was it helpful?

Solution

Well um, I think you're a bit off. A monad is an endofunctor, which in Hask (The category of Haskell types) is something with the kind F :: * -> * with some function that knows how to inject morphisms (functions) into the subcategory of Hask with functions upon Fs as morphisms and Fs as objects, fmap. What you have there appears to be a natural transformation in Hask.

Examples: Maybe, Either a, (,) a, etc..

Now a monad also must have 2 natural transformations (Functor F, Functor g => F a -> G a in hask).

n : Identity -> M
u : M^2 -> M

Or in haskell code

n :: Identity a -> M a -- Identity a == a
u :: M (M a) -> M a

which correspond to return and join respectively.

Now we have to get to >>=. What you had as bind was actually just fmap, what we actually want is m a -> (a -> m b) -> m b. This is easily defined as

 m >>= f = join $ f `fmap` m

Tada! We have monads. Now for this monoid of endofunctors.

A monoid over endofunctors would have a functors as objects and natural transformations as morphisms. The interesting thing is that the product of two endofunctors is their composition. Here's the Haskell code for our new monoid

type (f <+> g) a = f (g a)
class Functor m => Monoid' m where
    midentity' :: Identity a -> m a
    mappend' :: (m <+> m) a -> m a

This desugars to

 midentity' :: a -> m a
 mappend' :: m (m a) -> m a

Look familiar?

OTHER TIPS

The definition "Monads are just monoids in the category of endofunctors.", which although true is a bad place to start. It's from a blog post that was largely intended to be a joke. But if you are interested in the correspondence it can be demonstrated in Haskell:

The laymen description of a category is an abstract collection of objects and morphisms between objects. Mappings between categories are called functors and map objects to objects and morphisms to morphisms associatively and preserves identities. An endofunctor is a functor from a category to itself.

{-# LANGUAGE MultiParamTypeClasses, 
             ConstraintKinds,
             FlexibleInstances,
             FlexibleContexts #-}

class Category c where
  id  :: c x x
  (.) :: c y z -> c x y -> c x z

class (Category c, Category d) => Functor c d t where
  fmap :: c a b -> d (t a) (t b)

type Endofunctor c f = Functor c c f

Mappings between functors which satisfy the so called naturality conditions are called natural transformations. In Haskell these are polymorphic functions of type: (Functor f, Functor g) => forall a. f a -> g a.

A monad on a category C is three things (T,η,μ), T is endofunctor and 1 is the identity functor on C. Mu and eta are two natural transformations that satisfy a triangle identity and an associativity identity, and are defined as:

  • η : 1 → T
  • μ : T^2 → T

In Haskell μ is join and η is return

  • return :: Monad m => a -> m a
  • join :: Monad m => m (m a) -> m a

A categorical definition of Monad in Haskell could be written:

class (Endofunctor c t) => Monad c t where
  eta :: c a (t a)
  mu :: c (t (t a)) (t a)

The bind operator can be derived from these.

(>>=) :: (Monad c t) => c a (t b) -> c (t a) (t b)
(>>=) f = mu . fmap f

This is a complete definition, but equivalently you can also show that the Monad laws can be expressed as Monoid laws with a functor category. We can construct this functor category which is a category with objects as functors ( i.e. mappings between categories) and natural transformations (i.e. mappings between functors) as morphisms. In a category of endofunctors all functors are functors between the same category.

newtype CatFunctor c t a b = CatFunctor (c (t a) (t b))

We can show this gives rise to a category with functor composition as morphism composition:

-- Note needs UndecidableInstances to typecheck
instance (Endofunctor c t) => Category (CatFunctor c t) where
  id = CatFunctor id
  (CatFunctor g) . (CatFunctor f) = CatFunctor (g . f)

The monoid has the usual definition:

class Monoid m where
  unit :: m
  mult :: m -> m -> m

A monoid over a category of functors has a natural transformations as identity a and a multiplication operation which combines natural transformations. Kleisli composition can be defined to satisfy the multiplication law.

(<=<) :: (Monad c t) => c y (t z) -> c x (t y) -> c x (t z)
f <=< g = mu . fmap f . g 

And so you have it "Monads are just monoids in the category of endofunctors" which is just a "pointfree" version of the normal definition of monads from endofunctors and (mu, eta).

instance (Monad c t) => Monoid (c a (t a)) where
  unit = eta
  mult = (<=<)

With a bit of substitution one can show that the monoidal properties of (<=<) Are equivalent statement of the triangle and associativity diagrams for the monad's natural transformations.

f <=< unit == f
unit <=< f == f

f <=< (g <=< h) == (f <=< g) <=< h

If you're interested in diagrammatic representations I have written a bit about representing them with string diagrams.

It seems to me that you omitted important things:

  • There is the word “monoid” in the definition. You did not consider it in your post.
  • It is better to replace it with “monoid object” in order to be precise. Monoids live in abstract algebra, monoid objects live in category theory. Different species.
    • Monoids are monoid objects in some category, but this is not relevant here.
  • A monoid object may be defined in a monoidal category only.

So, a path to understanding the definition is as follows.

  • You consider a category of endofunctors (lets call it E) on the category of Haskell types and functions Hask. Its objects are functors on Hask, a morphism in it from F to G is a polymorphic function of type F a -> G a with some property.
  • You consider a structure on E which turns it into a monoidal category, i.e. composition of functors and the identity functors.
  • You consider definition of a monoid object, e.g. from Wikipedia.
  • You consider what it means in your specific category E. It means that M is an endofunctor, and μ has the same type as “join”, and η has the same type as “return”.
  • “(>>=)” is defined via “join”.

An advice. Do not try to express everything in Haskell. It is designed for writing programs, not mathematics. Mathematical notation is more convenient here because you can write composition of functors as “∘” without going into trouble with type checker.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top