Franklin Pezzuti Dyer

submited by
Style Pass
2024-05-10 01:00:05

I've been mulling over the idea of this blog post for a long time, probably since I wrote this older post describing a couple examples of monads. Monads are infamously tricky to grok, which is why I've been looking for examples to help myself understand the commonest Haskell monads that are as simple as possible, yet at the same time well-motivated (no Foo Bar Baz or any of that gibberish).

This post consists of a family of examples illustrating how monads allow us to easily implement dependency injection in Haskell, which is a design pattern whereby an abstractly-written function receives its dependencies "from outside", making it very easy to drastically change the function's behavior by manipulating the dependencies that it is given.

As a warning - this post isn't very beginner-friendly, and it's not an introduction to monads. The intended audience is someone (like me) who has been toying with monads for a little while but is struggling to get a "big picture" understanding of how they are powerful. If you have not programmed in Haskell and worked with monads before, you will probably have a hard time following what comes below, but I encourage you to download the code and load it into a REPL to tinker with regardless of your skill level.

The function into which we'll be "injecting dependencies" is a very simple one - we will just be writing an implementation for the following mathematical function: As a disclaimer, when I said that I wanted an example to "motivate" monads, that was coming from the mouth (fingers?) of someone who feels more comfortable in pure mathematics than software engineering, so not everyone will find this example as compelling as me. The above function is somewhat arbitrary, but I picked it specifically because it involves a couple of different mathematical operations that can be problematic, such as division and taking a square root. In a moment we'll see how various different monads can be used to define more robust versions of this function without rewriting any of its definition.

Leave a Comment