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 `Functor`

and `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 `Applicative`

. Or `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, `Alternative`

and `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`

, 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: `Contravariant`

, `Profunctor`

, and `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

Part I: `Functor`

and `Bifunctor`

- Introduction
- Motivation, higher-kinded types and
`fmap`

- Some product type functors, more examples of
`fmap`

usage - The functor of functions and some functors that are not
`Functor`

s - The
`Functor`

laws and property tests - Introduction to
`Bifunctor`

: what is this and why - An interesting bifunctor
- The
`Bifunctor`

laws and property tests

Part II: `Applicative`

Part III: Traversable and Alternative

- A monoid for applicative functors
`Traversable`

: what and why and what does this have to do with`Applicative`

- Concurrency!

Part IV: `Monad`

and monad transformers

Introduction

`Monad`

: what and whyInstances

Relationship to

`Functor`

and`Applicative`

Examples of

`>>=`

usageThe Kleisli fish

`Reader`

…`Reader`

everywhereThe

`Monad`

laws and property testsMonads do not compose: monad transformers

Interlude: An X that is not a Y

Part V: `Contravariant`

, `Profunctor`

, `Arrow`

- Introduction
`Contravariant`

: what and why- What kinds of types are contravariant
- Relationship to an earlier functor
- Examples of
`contramap`

usage - The
`Contravariant`

laws and property tests `Profunctor`

: what and why- Breaking down
`dimap`

- What kinds of types are profunctors
- Examples, from basic to complex
- The
`Profunctor`

laws and property tests `Arrow`

: What is this madness?- Situating
`Arrow`

- Functors and computation models

Wrapping up: So, then, what is *functoriality*?