# Why are monads important

**URL:** <https://discuss.ocaml.org/t/why-are-monads-important/8868>\
**Category:** Learning\
**Created:** [November 23, 2021, 2:00am UTC](https://discuss.ocaml.org/t/why-are-monads-important/8868 "2021-11-23T02:00:20Z")\
**Posts on this page:** 1\
**Showing post:** 6

<div class="post-metadata">

**Author:** ![ivg](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/ivg/32/103_2.png) [@ivg](https://discuss.ocaml.org/u/ivg)\
**Post date:** [November 23, 2021, 5:12pm UTC](https://discuss.ocaml.org/t/why-are-monads-important/8868/6 "2021-11-23T17:12:15Z")

</div>

> [@devosalain](#):
>
> I’m learning the language. I was wondering why are monads important or not?

The monad is a pattern that naturally arises in ~~functional~~ everyday programming. Even if it weren’t discovered, you will be still using it every day, just without knowing its fancy (and useless) name. Here are some examples.

Suppose you’re writing a program that has some configuration data, like command-line parameters, and you want to pass it to some of your functions that depend on it. So you have a bunch of functions that has type `config -> 'a` and you constantly threading this annoying `config` from the caller to callee, e.g.,

```auto
let main ctxt = 
  let x = do_one_thing ctxt in
  let y = do_another_thing x ctxt in
  x + y

```

As soon as we see a repetitive pattern, we should look for an abstraction opportunity. In this case, our abstraction is called the reader monad and has type `type 'a reader = config -> 'a`, so we can implement corresponding bind operation and write,

```auto
let main = 
  let* x = do_one_thing in
  let+ y = do_another_thing x in
  x + y

```

Next, suppose you’re writing code that threads the state, i.e., unlike the previous example, your functions may functionally update the passed configuration, and now instead of writing ugly code like,

```auto
let state,x = do_one_thing state in
let state,y = do_another_thing x state in
x + y

```

We can write a much more readable and less error-prone version, which uses the  
`type 'a state = config -> 'a * config` monad,

```auto
let* x = do_one_thing in
let+ y = do_another_thing x in
x + y

```

Now, let’s add another feature to our program. We’ve figured out that our functions can fail, so in addition to changing the state, we might also return an error. In this case, writing in the direct (non-monadic) style is even more painful and nearly impossible, e.g.,

```auto
match do_one_thing state with
| Error _ as err -> err
| Ok (state,x) -> match do_another_thing x state with
  | Error _ as err -> err
  | Ok (state,y) -> x + y

```

But in the monadic style it is still… you probably already guessed it,

```auto
let* x = do_one_thing in
let+ y = do_another_thing x in
x + y

```

So nothing changes, again. Notice how we were adding various effects and we didn’t need to change our business logic code. It is because we found the right abstraction. And this is the main power of monads, is that you’re able to write clear generic code and extend it without modification. This separation of concerns significantly reduces the cognition burden and you can focus on the business logic and forget about the implementation details. Thus monads enable you to tackle the more complex problems. That is especially true when you write parser-like code when you need backtracking and multiple choices.

But let’s return to our examples. You can see that the monadic version of the code is the same, the only thing that changes is the `let*` operator, which stands for the `bind` function (and `let+`, which stands for `map`, but is easily derivable from `bind`). This `let*` is the essence of the monad, as the monad is just an abstraction of the computation, i.e., it defines how terms are computed. And by abstracting it, or let’s say, reifying it into the `let*` operator, we can write generic code that doesn’t depend on how the computation unfolds. You can also think of the built-in `let` operator of OCaml as the monad, as well. It also offers error handling and state, but is less general (no backtracking, non-determinism) and, the main problem, too invasive. All computations are naturally embedded into the OCaml monad, so we can’t really say which computation is pure and which is not from its type. Unless we embrace some discipline and refrain from using the OCaml monad and stick to explicit monads.

To summarize, a monad is just an algebra of computations. We have `int` that is an algebra of integers, we have `Set` that is the algebra of sets. And we have the algebra of monads, which captures the idea of computation, i.e., evaluating a term and binding it to a result, i.e.,

```auto
type 'a t
val return : 'a -> 'a t
val (let*) : 'a t -> ('a -> 'b t) -> 'b t

```

Computations are so natural in our everyday programmer’s life, that we don’t even notice them, and don’t think about them as abstractions, thinking that it is the responsibility of the programming language abstract machine to carry computations for us. It turns out, that if we will take this power from the language and put it under our control, we can make wonders.

> [@yawaramin](#):
>
> And the future direction of the language (with algebraic effects) will make them even more so.

Algebraic effects will enable more efficient and straightforward implementations of monads, especially those that deal with non-pure effects, such as the IO monad. But by no means do they substitute the concept of the monad. In other words, the effects system is the implementation details, like algebraic data types, records, exceptions, etc. Not to be confused with the monad, which is an abstraction that can be implemented with effects, ADT, functions, etc.

---

_[View the full topic](https://discuss.ocaml.org/t/why-are-monads-important/8868)._
