Monads (and other Functional Structures)
Monads are one of the most feared topics for beginners coming to Haskell. But like most programming concepts, they’re not nearly as scary once you actually understand what they are. There are numerous tutorials out there and just as many definitions of what a monad really is and how to explain it to people. This series is Monday Morning Haskell’s attempt to alleviate this sore spot for those just getting into Haskell. We’ll work our way up from the basics, starting with functors and applicative functors to get an intuition for how abstract structures work in Haskell. Then we’ll tackle monads and look at some of the most common ones.
In part 1, we’ll learn all about functors. These are the simplest Haskell structure to learn about. They are very intuitive, and their typeclass has only a single function. This will help us start building an understanding of abstract structures with a simple example.
In part 2, we tackle applicative functors. Applicatives are a little more difficult to understand than functors, but their functionality can still be summed up in a couple simple functions.
In part 3, we finally approach the topics of monads. Now that we have an intuition for how abstract structures work, we’ll examine some of the problems that applicative functors and functors DON’T help us solve. Then we’ll get into the specifics of how we actually use monads.
Our introduction to monads examined the built in types that have a monadic structure. It had a focus on those things that we’ve seen in action, but maybe never thought of monadically. In part 4, we start exploring some of the common monadic idioms that you’ll need outside of the basics. We’ll examine the
Reader monad, which gives us a global readable state, and the
Writer monad, which allows us to keep a running value throughout our computations.
Part 5 picks up where part 4 left off, and introduces the
State monad. This monad allows us to keep a particular type that we can both read from and write to. It opens the door to fully stateful programming, allowing us to do many of the things Haskell supposedely “can’t” do.
By this point, we’ve been exposed to plenty of different monads. But now we need to answer the question of how we can make them work together. After all, there are definitely times when we need multiple kinds of monadic behavior. Part 6 introduces the concept of monad transformers, which allow us to combine multiple monads into one.
In the seventh and final part of this series, we’ll examine what makes a monad a monad. After all, can you just implement these typeclass any way you want and write a “monad” instance? Starting back with functors and applicative functors, we’ll learn that all these structures have “laws” that they are expected to obey with respect to their behavior. We can make instances that don’t follow these laws. But we do so at our peril, as other programmers will be very confused by the behavior.
The one chief takeaway of this series is that monads are NOT SCARY. It might take a couple tries to really learn them, but it’ll come! Many people give up on Haskell altogether because they get frustrated by this topic. If you’ve considered learning Haskell but have been afraid to start because of monads, never fear! Download our beginner’s checklist to start learning the language, then you can try out all the tricks in this series.
If you’ve made it through this series, congratulations! You can now start to level up your Haskell skills by learning more advanced techniques and libraries. For some ideas, check out our Production Checklist.