My category theory is not strong at all (I started from the programming side of Haskell and have been recently trying to learn some of the category theory foundations of some of its concepts). But here's what I've got:
In Haskell, a functor is a type constructor, meaning it maps from general types to "types in the functor".
In category theory, a functor maps from the objects of one category to the objects of another category.
When applying category theory to Haskell, we imagine that we're working with the category Hask, the category of Haskell types.
So Haskell functors aren't general category theory functors; they all map from Hask to a sub-category of Hask (because the type f a
for some functor f
and arbitrary type a
is still a Haskell type). For example the Maybe
functor maps objects (types) in Hask to the category of types of the form Maybe a
.
Functions are first-class in Haskell, so function types are perfectly ordinary types (and are objects of Hask) so functors also map function types to "function types in the functor". So the phrase "a function inside a functor" is a shorthand for a value in a type that results from applying a functor to a function type. e.g. Just (+1)
is one particular value in the type Maybe (Int -> Int)
, which is the object (type) to which the Maybe
functor maps the object Int -> Int
.
So an "applicative functor" is a functor which has some extra rules, which are sufficient to take values which are functions in types which are objects of the functor's "destination" category, and apply those values to other values in types in the destination category.
Using Maybe
again as an example, if we only knew it was a functor that gives us a correspondence between the objects Int -> Char
and Maybe (Int -> Char)
, and between the objects Int
and Maybe Int
, and between the objects Char
and Maybe Char
. But while we have the ability to take a value in Int -> Char
and a value in Int
and produce a value in Char
, Maybe
being a functor doesn't guarantee that we have any ability to do some corresponding operation with a value in Maybe (Int -> Char)
and a value in Maybe Int
.
When we also know it's an applicative functor, then we do have an ability to take a value in Maybe (Int -> Char)
and a value in Maybe Int
and produce a value in Maybe Char
, and this satisfies certain properties wrt the application of Int -> Char
values to Int
values.
As far as I know, applicative functors aren't terribly interesting from a pure category theory standpoint. Perhaps this is because category theory is concerned with relationships between objects, which correspond to types in Haskell, but from a programming perspective applicative functors are motivated by relationships between values in those types? (we want the values in the "function types" obtained by using the functor to still be able to be applied to things to do computation).