Haskell Monads

* Monad* is a type class that declares the function

The *return* function takes a value and returns it inside the minimal context of the monadic type thus preserving that value. For example *return 1*, when in the List monad, returns *[1] - *Why *[1]*? Well, *[]* would be minimal, but does not preserve the value, whereas *[1,1]*,* [1,1,1]*, ... *[1..]* are not minimal.

To be "in the List monad" just means that we are using *return* or *bind* when working with values of type [a]. *return* and *bind* are overloaded; their type-specific behaviour is defined in their type class instance.

Similarly, when in the *Maybe* monad, *return 1*, returns *Just 1* since alternatively *Nothing* does not preserve the value.

*return* wraps a value in a monadic value and returns it. It's a function and not a statement and is not to be confused with the "return" common to imperative languages.

The bind operator *>>=* has the following type signature.

Monad m => m a -> a -> m b -> m b

or equivalently:

Monad m => m a -> ( a -> m b ) -> m b

As you can see, the first argument of the bind operator is a monadic value, the second a function that takes a plain value and returns a monadic value, and the result of the bind operator is the value returned by that function. In other words, bind allows us to apply a function that expects a plain value to a monadic value.

It allows us to chain functions (like the *.* operator for ordinary functions) whilst preserving the context of the computation.

For example, when chaining functions in the *Maybe* monad the context is one of computational failure akin to Exceptions. A failure is indicated by the value *Nothing*. If we chain two or more functions and any one of them fails the result ought to be *Nothing*.

Let's say we perform two DB lookups. The first takes a primary key and returns *Just table1record*, where *table1record* contains some foreign key. The second lookup takes that foreign key to lookup another record in *table2*. Clearly either the first or the second lookup can fail (i.e. return *Nothing*) in which case the chained function calls should also return *Nothing*. (Only if both calls find matching records the chained calls return a value of* Just table2record*.)

The bind operator for the *Maybe* monad knows that and handles *Nothing* for us so that we don't have to check at every step whether a computation failed (i.e. returned *Nothing*). This is nice, because it saves us from typing the repeated check manually.

So the context of the *Maybe* monad is one of **failure**. What's the context of the List and IO monads?

For lists it's **indeterminism**, i.e. a computation that returns a list of zero, one or more results. (Remember school: What's the square root of four? It's both 2 and -2.) When we bind functions under the list monad, we expect the computation to return no results if any one computation returns none and one or more results otherwise. For example, if some computation A returns two results and applying those two results in turn to some computation B that for the first result returns 3 and for the second returns 4 results we expect the chained operation to return a total of 7 results. This makes intuitive sense: If some computation or process has an uncertain outcome and we apply that outcome to yet another process that is also uncertain, overall uncertainty with respect to the final result grows quickly. The list monad factors this behaviour out, just as the *Maybe* monad factors out Exception bubbling.

The context for the IO monad is **side effects**.

Another benefit of monads is Do notation. Do notation is syntactic sugar (i.e. a convenient notation that is just expanded to nested binds and returns) that makes it easy to write a sequence of computations, separated by semicolons. In the case of the *Maybe* monad, as explained above, this means that if one computation fails the chained/overall computation fails. Since the same do notation is used with different monads some call this the **programmable semicolon**. It's programmed in the bind implementation of the monad type class instance.

Part II to follow...

Nothing quite helps me to understand a topic better than trying to explain it in a writeup. This is my understanding of monads but I am only a beginner. Please correct me.