Monads were created by mathematicians in 1960 and rediscovered by computer scientists in 1990 as a new way to handle effects. Let's write some examples: imagine a function that gets the first element from a list like this
```haskell
head :: [a] -> a
head (x : xs) = x
head [] = ?
```
The problem here is obvious, we have an effect because this function can fail if it receives an empty list, now imagine that for any reason we're using this function in our program to work if the list and for some reason, it receives an empty list, in this case, our program will break and the language compiler will give to us an exception, so how to solve this? to solve this we can use the Maybe Monad, let's write this:
```haskell
safeHead :: [a] -> Maybe a
safeHead (x : xs) = Just x
safeHead [] = Nothing
```
Now we have the `safeHead` function that is total, which means that this function will never fail, even if receives an empty list. As you can see, a Maybe Monad is like a box that encapsulates a value, so this box can have some value or nothing. Let's write our own Maybe Monad in Haskell:
```haskell
data Maybe a = Just a | Nothing
```
As you can see the Maybe Monad allows us to handle functions that can fail, but now that these values are encapsulated how we can work with him? Monads essentially are functors so we can map functions in our monads without changing your structure, let's have an example with lists:
```haskell
> fmap (+1) [1,2,3]
[2,3,4]
```
Here we map the function "+1" in our list. As you can see we don't change its structure, and that's basically what functors allow us to do. But, what if we want to pass our boxed value to some function that takes just a value and transform this in another type of monadic value? We can use the bind operator for this, which is one of the functions necessary for the implementation of a monad. In Haskell, this is represented by the symbol `>>=`. Imagine that we want to use our "safeHead" function from before and now we want to pass the first element from a list to a function that takes some value and tell us if this value is even or not, to do this first of all we need this even function:
```haskell
isEven :: Num a => a -> Maybe Bool
isEven n = Just $ even n
```
After writing this we can pass our element to this function using the bind operator, let's write this:
```haskell
> safeHead [1,2,3] >>= isEven
Just False
> safeHead [] >>= isEven
Nothing
```
One thing that you can notice here is that the isEven function also returns a Maybe Monad, so what the bind operator do is get the value from the box and put him back in the box after doing something. This helps us to compose our monadic functions handling all the effects that we can find on the way.
So the central point here is that Monads allow us to handle effects, like for example handle Input/Output with IO Monad. This is very powerful because it allows us to have handled effects with pure functions, meaning that it also allow us to build real-world applications with pure languages like Haskell.
A little explanation about this: Haskell, for example, is a pure language which means that we just have pure functions. Pure functions are like mathematical functions: it will produce exactly the same output given the same input, so it's not possible to have side effects, for example. While building a real-world application, on another note, we need to handle side effects like get some data typed by the user, or read some file. So we may think that Haskell is a useless language, but Monads allow us to handle this effects while maintaining the functions pure.