I read this excellent blog article on natural transformations[1], which helped me gain one intuition as to what they are: "functions that don't make too many assumptions about their arguments". In the article, natural transformations make "no assumptions at all" about their arguments. However, it's often the case that a Haskell function will require a type argument constrained by a type class, e.g. show :: Show a => a -> String. I wondered if it was possible to characterise these functions using category theory too. Below is my attempt, and I'm hoping people can tell me whether I'm in the right ballpark (or point me in the direction of a better ball-park...)
For a particular type class T, we can form a subcategory Hask_T of Hask consisting of all the instances of the type class as objects, with the arrows just those functions that "commute" with the signature of the type class. For example, in Hask_Show, the arrows would be all the functions f: A -> B such that:
show == show . f
Or for Data.Monoid, all the monoid homomorphisms f:
mappend (f x) (f y) == f (mappend x y)
mempty == f mempty
In general, for any type class, we can formulate two functors f and g and a function sig :: f a -> g a that captures the operations in the type class, and then the condition is that:
fmap f . sig == sig . fmap f.
Then we have that the polymorphic functions with a type class constraint of T are just the same thing as natural transformations in this subcategory Hask_T.
Is the above correct / along the right lines?
Thanks,
-- Matt