The basis of things to come
[This article was expanded on 2020-04-06.]
The first place to look for an introduction to any structure is Hackage, which covers
Functor pretty well. Consider this article a commentary on that page.
There we are told Functors are:
uniform action over a parameterized type, generalizing the map function on lists.
The class provides a single higher order method for converting the parameter type of the functor.
If the transformer function,
f is of type
fmap f will convert
Baz Foo values into
Baz Bar values.
<$> operator is used. It is but an alias for
Functors are really quite primal and I would advise anyone starting out with Haskell prioritising getting used using them, stacks of them. If you have an
IO action that returns a
but you need a
Maybe T.Text then this should be quite natural (bearing in mind that, like many useful types,
Maybe are functors):
fmap T.pack (in this context) is of type
which is just a function we can apply as an argument to
<$> are the same function (in the standard
Prelude anyway) so this is equivalent to:
[Notice the way that whole explanation of stacked functors took place entirely in the land of types — this is a central feature of Haskell that every Haskell program or fragment has a dual life: a static life in types and a dynamic life at runtime.]
The above pattern is so pervasive that it is worth getting familiar with, especially in an
f <$> action (or
fmap f action) applies some arbitrary function
f to the output of the
But this is bur a single pattern. Functors can be applied pretty much anywhere.
Functor provides some useful auxiliary operators and functions.
is equivalent to this
forcing the output of
s to a constant value:
is the same operator as
<$, but with its arguments flipped:
so we could have written above:
is a flipped version of
so we can say
This is just a special case of
$>) that force the output of the functor to the unit type
Above, e could have written:
Best is yet to come
In [the notes for
($) on the Hackage
Functor page notes the symmetries between the function application operator
This is not accidental and totally in keeping with the way it is used, including the examples at the top of this article.
($) can be used to transform the output of a function, so
(<$>) can be used to transform the output of a Functor.
But hold on a minute, aren’t we getting ahead of ourselves,
getEnv is an
IO, a famous monad, not a Functor? But all monads are applicatives and all applicatives are functors, so monads are functors of course.
Everything we are saying about functors is true of applicatives (and monads), and everything we say about applicatives will be true of monads. This compositional understanding is important to understanding the big picture, and as we can see it provides an accessible place to start.
Functors come from abstract algebra and, as we are reminded at the top of the top Functor Hackage page, where they are characterised by the following identities.
That these simple identities (along with those for the other structures) can give rise to all of this is truly a wonderous thing!
Got an issue with any of this? Please share or drop me a line (see below).