# Monad

{ This is my poor understanding of a monad. I am not actually sure if it's correct lol :D TODO: get back to this. ~drummyfish }

Monad is a mathematical concept which has become useful in functional programming and is one of the very basic design patterns in this paradigm. A monad basically wraps some data type into an "envelope" type and gives a way to operate with these wrapped data types which greatly simplifies things like error checking or abstracting input/output side effects.

A typical example is a **maybe** monad which wraps a type such as integer to handle exceptions such as division by zero. A maybe monad consists of:

1. The *maybe(T)* data type where *T* is some other data type, e.g. *maybe(int)*. Type *maybe(T)* can have these values:
  - *just(X)* where *X* is any possible value of *T* (for int: -1, 0, 1, 2, ...), or
  - *nothing*, a special value that says no value is present
2. A special function *return(X)* that converts value of given type into this maybe type, e.g. *return(3)* will return *just(3)*
3. A special combinator *X >>= f* which takes a monadic (*maybe*) values *X* and a function *f* and does the following:
  - if *X* is *nothing*, gives back *nothing*
  - if *X* is a value *just(N)*, gives back the value *f(N)* (i.e. unwraps the value and hand it over to the function)

Let's look at a pseudocode example of writing a safe division function. Without using the combinator it's kind of ugly:

```
divSafe(x,y) = // takes two maybe values, returns a maybe value
  if x == nothing
    nothing else
    if y == nothing
      nothing else
        if y == 0
          nothing else
            just(x / y)
```

With the combinator it gets much nicer (note the use of lambda expression):

```
divSafe(x,y) =
  x >>= { a: y >== { b: if b == 0 nothing else a / b } }
```

Languages  will typicall make this even nicer with a syntax sugar such as:

```
divSafe(x,y) = do
  a <- x,
  b <- y,
  if y == 0 nothing else return(a / b)
```

TODO: I/O monad
TODO: general monad
TODO: example in real lang, e.g. haskell