### A simple introduction to why Monads are useful

We would like to be able to describe all of the basic types of I/O operations, e.g. write text to standard output, read text from standard input, read and write files, send data over networks, etc. In addition, we need to be able to compose these primitives to form larger programs. For example, we would like to be able to perform some basic operations with I/O actions: We should be able to sequence two I/O operations together. In Haskell, this is written as an infix operator >>, so that putStrLn "abc" >> putStrLn "def" is an I/O action that prints two lines of text to the console. The type of >> is IO a ° IO b ° IO b, meaning that the operator takes two I/O operations and returns a third that sequences the two together and returns the value of the second. We should have an I/O action which does nothing. That is, it returns a value but has no side effects. In Haskell, this action constructor is called return; it has type a ° IO a. The given function is applied to all of those values to obtain values of type (M u). m >>= return = m Binding two functions in succession is the same as binding one function that can be determined from them: return { "name":"Homer Simpson", A binding operation of polymorphic type (M t)?(t°M u)?(M u), which Haskell represents by the infix operator >>=. Its first argument is a value in a monadic type, its second argument is a function that maps from the underlying type of the first argument to another monadic type, and its result is in that other monadic type. Typically, the binding operation can be understood as having four stages: console.log(state); } }; var Something = function(value) { let! y = readNum() if (y = 0) }, The function then creates a new monadic value M b that can be fed to the next bind operators composed in the pipeline. With these elements, the programmer composes a sequence of function calls (the "pipeline") with several bind operators chained together in an expression. Each function call transforms its input plain type value, and the bind operator handles the returned monadic value, which is fed into the next step in the sequence. Between each pair of composed function calls, the bind operator can inject into the monadic value some additional information that is not accessible within the function, and pass it along. It can also exert finer control of the flow of execution, for example by calling the function only under some conditions, or executing the function calls in a particular order. For example, the following code defines a binary operator x//y as safe division that avoids dividing by zero, using the Maybe monad and its constructors Nothing and Just.[a] The monadic values x and y are extracted into the plain values a and b, which are processed by the plain division operator "/" only when b is not zero. In the third example expression, a pipeline that chains together two safe divisions, the result of the bind. Fortunately, with our new Maybe type we can do all this and more. Here's the final Maybe code with a few new methods (isNothing, val and maybe) that provide some additional utility: Maybe = function(value) { var Nothing = {}; var Something = function(value) { }, if (y = 0) "street":"123 Fake St.", return function() { The monad-related structure on the first argument is "pierced" to expose any number of values in the underlying type t. = id fmap (f . g) = join (fmap g m) Here, m has the type M (M r), f has the type t ? u, and g has the type t ? u, and g has the type t ? u, and g has the type t ? u, and g has the type t ? u, and g has the type t ? u, and g has the type t ? u, and g has the type t ? u, and g has the type t ? u, and g has the type t ? u, and g has the type t ? u, and g has the type t ? u, and g has the type t ? u, and g has the type t ° M v, where t, r, u and v are underlying types. The fmap function is defined for any functor in the category of types and functions, not just for monads. It is expected to satisfy the functor laws: fmap id = (fmap f) . (fmap g) The return function characterizes pointed functors in the same category, by accounting for the ability to "lift" values into the functor. It should satisfy the following law: return . f = fmap f . return This is equivalent to stating that return is a natural transformation from "fmap . fmap" to "fmap". Additive monads An additive monad is a monad endowed with a monadic zero m0 and a binary operator mplus satisfying the monoid laws, with the monadic zero as unit. The operator mplus has type M t ° M t ° M t ° M t ° M t ° M t ° M t ° M t ° M t (where M is the monad constructor and t is the underlying data type), satisfies the associative law and has the zero as both left and right identity. That is: (a + b) + c = (fmap f) . (fmap g) The return function characterizes pointed functors in the same category, by accounting for the ability to "lift" values into the functor. It should satisfy the following law: return . f = fmap f . return This is equivalent to stating that return is a natural transformation from the identity "id" to "fmap". In addition, the join function characterizes monads: join . fmap join isNothing: function() { }; }; if (typeof value === 'undefined' || value === null) return false; } else { "street":"123 Fake St.", console.log("State unknown"); } } All those null checks are fairly ugly. They're tedious to write and annoying to read, an unfortunate side-effect of working in a language in which null was implemented rather poorly. Is there perhaps a way to factor them out? Yes there is. Maybe We Have a Solution What we want is to embed the computation of != null into a function or type or class that we can easily re-use so that we don't have to spatter our code with null checks. This is exactly what the Maybe monad provides. In Haskell, the definition of type Maybe is rather succinct: data Maybe t = Just t | Nothing All this means is that an object of type Maybe either has some value (Just t) or no value (Nothing). What is meant by Nothing depends on the context. In JavaScript the only things that mean "nothing" are null and undefined. But as you will see, with the Maybe monad, we can change the semantics of "nothing" to suit our needs. We can begin to model the Haskell definition in JavaScript as follows: Maybe = function(value) { var Nothing = { The monad-related structure on the first argument is "pierced" to expose any number of values in the underlying type t. console.log(state); } }; var Something = function(value) { }; }; if (typeof value === 'undefined' || value === null) return Maybe(fn.call(this, value)); = a + (b + c) m + m0 [1..2] The monad-related structure on the first argument is "pierced" to expose any number of values in the underlying type t. console.log("State unknown"); } } So far, all we have done is replace a null check with a check for Nothing. This is not quite what we want. Maybe We Need Composition One of the defining characteristics of a monad is that it may be combined with other monads of the same type. That is, we should be able to sequence monads together through composition. You may remember that function composition is the application of one function to the result of another. Mathematically, given two functions g and f, the composition of g of f is: (g°f)(x) = g(f(x)) In the case of Maybe, we need some way to take multiple Maybes and combine, chain or bind them together in a meaningful way. This way, if one Maybe is Nothing we can short-circuit our computation and stop at Nothing, otherwise we can continue on our way, essentially replicating what the && provides in our first example. (Technically, in JavaScript the computation does not short-circuit as it would in a lazy language like Haskell, but the effect is the same.) We can do this by introducing a method on Maybe called bind (in Haskell, this is the >>= operator) that makes specific use of function composition. This bind method applies a function to the value contained by a Maybe and returns a new Maybe that contains the value of the function application. Since Nothing has no value, anything bound to a Nothing should simply return Nothing (our short-circuit). Maybe = function(value) { var Nothing = {}; var Something = function(value) { }, maybe: function(def, fn) { = m Thus, an additive monad is also a monoid. For >>=, on the other hand, m0 acts as a null-element. Just as multiplying a number by 0 results in 0, binding m0 with any function produces the zero for the result type: