This course as a whole will be a full tour of the functors. We will start by examining the motivation for functors and the
Functor typeclass. From there, we’ll explore monoidal functors, bifunctors, contravariant functors, and profunctors in depth, discussing the laws and the mathematical basis for these structures along the way.
In order to simplify navigation and provide more context, we’ve divided this course into four major sub-courses. The first covers
Bifunctor and provides a complete survey of those two typeclasses, how they relate, and why they exist. This first part assumes little in the way of prior Haskell knowledge, although some basic understanding of types and typeclasses will be helpful, along with some prior experience reading and understanding Haskell syntax.
While all the remaining components of this course rely on a solid understanding of
fmap and will refer back to lessons from the
Functor series, if you already understand that well, you may be looking to jump straight into
Monad, or one of the other, later topics, once those are written. The
Applicative series covers that typeclass in great detail as well as two closely related typeclasses,
Traversable. Monads get a lot of attention, for historical reasons (to wit: they appeared in Haskell long before applicatives did), but the trio of typeclasses featured in this series is incredibly powerful and should not be underestimated.
The next series within the Functortown course covers the
Monad class and related topics, including monad transformers. We will survey some of the most important, need-to-know monads and how they work and how they work in example programs. We’ll then take a brief pause to consider an X that is not a Y: a functor that is not a
Functor that is not an
Applicative, and so on, and what this tells us about typeclasses.
Finally, the course will conclude with a series on some oddballs:
Arrow. Interestingly, the first two are becoming more important in contemporary Haskell than they formerly were, while the popularity of
Arrow seems to be declining somewhat. We think, however, that all three deserve comprehensive treatment and discussion of how they fit into the larger body of functorial typeclasses within Haskell. The Functortown course will conclude with a summary of what functors are.
Each series within this course starts from a motivating example: we have a problem that we’re trying to solve, and we write a function to solve it. That function turns out to be a concrete instance of a more generic, reusable function – the function that is at the heart of the typeclass we’ll be discussing. Each series covers representative instances and practical uses of each typeclass. Additionally, we cover the laws of each typeclass and how to property test your instances using the
hedgehog testing library; however, in each case, we do this after the functions and uses of the typeclass have been thoroughly discussed.
The complete course plan
- Motivation, higher-kinded types and
- Some product type functors, more examples of
- The functor of functions and some functors that are not
Functorlaws and property tests
- Introduction to
Bifunctor: what is this and why
- An interesting bifunctor
Bifunctorlaws and property tests
Part III: Traversable and Alternative
- A monoid for applicative functors
Traversable: what and why and what does this have to do with
Monad and monad transformers
Monad: what and why
The Kleisli fish
Monadlaws and property tests
Monads do not compose: monad transformers
Interlude: An X that is not a Y
Contravariant: what and why
- What kinds of types are contravariant
- Relationship to an earlier functor
- Examples of
Contravariantlaws and property tests
Profunctor: what and why
- Breaking down
- What kinds of types are profunctors
- Examples, from basic to complex
Profunctorlaws and property tests
Arrow: What is this madness?
- Functors and computation models
Wrapping up: So, then, what is functoriality?