***A Monad is just a monoid in the category of endofunctors. ***
What’s the problem? Why are you crying?
Well… The problem… is that there are several problems.
In addition to it begin useful, it is also cursed and the curse of the monad is that once you get the epiphany, once you understand – „oh that’s what it is” – you lose the ability to explain it to anybody.
— Douglas Crockford
TL;DR
Eugenio Moggi discovered that computational effect can be mapped to monads. This turned out to be an important observation that not only gave denotational semantics a new lease on life and made pure functional programs more usable, but also shed new light on traditional programming
• Monads are a pattern of using types to encapsulate some data.
The true problem behind the endless pain of explaining what a monad is, is that it is too abstract and abstractions can be very confusing.
When people talk about monads they rarely mention the “Kleisli Arrow”, which was the key for me to understanding monads. If you are lucky they explain it using fmap and join, but if you are unlucky, like me, they explain it using the bind function. Why?
Because
bindis the function in Haskell that you need to implement for your type if you want it to be considered aMonad.https://betterprogramming.pub/monads-for-go-programmers-6cda2b978cb1
The
**>>=**** **operator allows you to chain multiple Lwt computations together in a way that makes it clear how the results of one computation are passed to the next.
Everything get worst when the “Monad” topic is introduced with the **disillusion **that monads exists as a silver bullet to avoid / destroy side effects and create a completely “pure” language.

After getting sick by frustration trying to figure out what a monad really is, I ended up writing this:
The true nature of monads (they don’t want you to know this)
But in practice, you should know that:
- Generally speaking monads are used to make things composable. Many different things (such as computations or data containers) can be expressed as monadic types.
- A *monad *is more of a design pattern than a data structure.
- Monads are used to model computations.
- A monad wraps a plain value into a context (stores a plain value inside a struct with more variables that represents a context):
/Untitled-380.png)
It comes from the “Category Theory”
The “monad” concept comes from “category theory”. More precisely: monadsare functors, so a functor is a superclass of a monad,
https://www.youtube.com/watch?v=gHiyzctYqZ0&list=PLbgaMIhjbmEnaH_LTkxLI7FMa2HsnawM_&index=20&t=4s
Monadic types are used in purely functional languages to wrap up things that are otherwise difficult to describe in pure functions (like side effects). While monads have other uses, they are often used as way to turn a side-effect into a value (because everything has to have a value in a pure function).
data Maybe a = Nothing | Just aIn Haskell we have a Maybe type which models computations that can fail. In Java you just use a null pointer which can belong to any type.
- This means the type checker has no idea if you have the potential to return null pointer or not. These null pointers tend to go unchecked as a result and therefor null pointer exception is an extremely common issue in Java.
- The same happens in Python with null and Perl with undef.
- C usually just does something like return -1 which is actually a valid member of the type and thus can lead to errors in logic that never even cause a crash.
Languages like Haskell and ML take a more principled approach and reflect this potential failure in the type.
The problem with monads is… they are very hard to compose.
A monad is an abstraction that can be used to parametrize code with the way how computations are sequenced. A monad can also be seen as design pattern, that sometimes makes your code more readable (and, more often, less readable).
- monad as generic concept describes how to build chains/pipelines of operations while concrete monad type defines what it actually means to chain/compose operations.
https://binaryanalysisplatform.github.io/bap/api/master/Monads.Std.html
Thus we can extract two concepts here:
- Monad – provides the abstract interface for monadic operations.
- Monadic type – a particular class that implements monadic operations
(Thinking of Monad as interface and monadic type as its implementation might be a good initial approach)
Monad Laws
/Untitled-381.png)
https://wiki.haskell.org/Monad_laws
Associativity:
The **>>=**** (bind) **operator follows the “associativity” law, which is one of the key properties of monads.
The associativity law for monads states that, for any monadic values **m1**, **m2**** and **m3**, and any monadic functions **f** **and **g**, the following should hold:
(m1 >>= f) >>= g = m1 >>= (fun x -> f x >>= g)This property allows the user to chain computations in multiple ways without changing the final result. This is known as “associativity” and it allows the user to structure the code in a way that is most readable and maintainable.
This can be demonstrated by the following:
let m = Some 3
let f x = Some (x + 1)
let g x = Some (x * 2)
let associativity_1 = option_monad#bind (option_monad#bind m f) g = option_monad#bind m (fun x -> option_monad#bind (f x) g) (* Some 8 = Some 8 *)In this example, I’ve implemented a simple Option Monad, but this pattern can be applied to other monads as well. Monads are a powerful tool in functional programming that allows you to abstract away from side-effects and make your code more readable, composable and easy to reason about.
Left Identity:
**return x >>= f = f x**
The “left identity” law for monads states that, for any monadic value **m**** **and any monadic function **f**, the following should hold:
return x >>= f = f xwhere **return x** is the function that wraps a plain value **x**** **into a monadic value.
This property is saying that if you take a plain value and wrap it in a monadic value using **return**** and then immediately apply a monadic function **f** to it using **>>=**, the result should be the same as if you had just applied the function **f** **to the plain value without wrapping it in a monadic value.
let x = 3
let f x = Some (x + 1)
let left_identity = option_monad#bind (option_monad#return x) f = f x (* Some 4 = Some 4 *)This property is important because it ensures that the **return** function behaves in a way that is consistent with how we expect functions to behave. It allows you to “inject” plain values into the monadic context in a way that is predictable and easy to understand, and that the resulting computation behaves in a way that is consistent with how we expect computations to behave.
The left identity law is often used as a starting point for building more complex computations, and it helps ensure that the basic building blocks of the computation are correct and that the resulting computation behaves as expected.
Right Identity:
**m >>= return = m**
The **Return**** function is a way to lift a plain value into a monadic value. In other words, it wraps a plain value inside the monadic context. The **Bind** **operator, also known as “flatMap” or “>>=” in some languages, applies a function to a monadic value and returns a new monadic value.
This law states that if we take a monadic value **m** and apply **>>=** to it with **return**, the result should be the same as the original monadic value **m**. This can be demonstrated by the following:
let m = Some 3
let right_identity = option_monad#bind m option_monad#return = m (* Some 3 = Some 3 *)The right identity law expresses the fact that if we have a monadic value **m** and we use the **Return** function to lift it into the monadic context again, we should get the same value back.
In the Maybe monad example I provided earlier, this would look like this:
m := Return(3)
n := m.Bind(Return)In this case, **n** should be the same as **m**, which holds the value **3** with **ok** set to true.
The right identity law is important because it ensures that we can always “unwrap” a monadic value back to its original form without losing any information, and it allows for better composition of monadic functions.
Monadic Values and Monadic Contexts
A “monadic value” is a value that is wrapped in a monadic context. The specific meaning of a “monadic value” can vary depending on the context and the monad in question.
A “monadic context” is a specific context in which a monadic value is evaluated. It can include various things such as:
- the state of the computation
- the environment in which the computation is executed
- the effects that the computation may have on the outside world (e.g. IO operations)
- the error handling strategy
The specific meaning of a “monadic context” can vary depending on the monad in question. But it can be understanded as a “metadata” tied to the plain value.
Take the following golang example, the “ok” field of the struct is the “monadic context”, and as you might expected, it’s possible to add more fields: more fields → more metadata → more context
The “monadic context” (that is sometimes is just a compose of the plain value with some metadata) is what makes monads hard to compose
Explaining Monads with a Golang example
Explaining Monads with a Java example
https://betterprogramming.pub/monads-for-go-programmers-6cda2b978cb1
https://bartoszmilewski.com/2016/11/30/monads-and-effects/
https://wiki.haskell.org/All_About_Monads
https://gist.github.com/fatcerberus/beae4d15842071eab24fca2f0740c2ef
https://users.rust-lang.org/t/what-is-a-monad-and-who-needs-haskell-anyway/45710
https://hoverbear.org/blog/option-monads-in-rust/
https://johnazariah.github.io/2022/12/06/this-is-not-a-monad-tutorial.html
https://vm.codes/blog/demystifying-monads
https://www.youtube.com/watch?v=nGhoZzihbHY
https://blog.ploeh.dk/2022/03/28/monads/
https://www.boringcactus.com/2020/07/18/monads-without-the-bullshit.html
https://www.microsoft.com/en-us/research/wp-content/uploads/1993/01/imperative.pdf
https://www.microsoft.com/en-us/research/wp-content/uploads/2016/07/mark.pdf