### A simple introduction to why Monads are useful

Functional programmers often cringe when they hear the term. JavaScript legend Douglas Crockford once said that monads are cursed - that once you understand monads for yourself you lose the ability to explain them to others. In the programming language F#, monads are called "computational expressions" mostly so people aren't scared away. But I think all this fear and mysticism around the dreaded "M-word" need not be so. So in this post, I'm going to attempt to put a small crack in the curse, not by attempting to explain all of monad theory in general, but instead by thoroughly diving into a concrete example of a monad in a specific language: the Maybe monad in JavaScript[1]. If you've been putting off learning about monads - or maybe have never even heard of them until now - then this post is for you. It will provide just enough material to give you a sense of what monads are and what they can do. From there you should have a solid stepping off point from which you can jump into reading something like this without trepidation. If you're a seasoned developer, chances are you have already used monads in your daily practice without even realizing it. For instance, a jQuery Deferred object is a monad. So is jQuery Ajax, as well as Bacon.js EventStream. So this shouldn't be too hard to follow. On occasion, I will reference similarities between the JavaScript example and its counterparts in the programming language Haskell. I do this only because most formal literature on monads references Haskell, and it helps to become familiar with the language. Feel free to skip these parts if you prefer. Maybe We Have a Problem After the Identity monad, the Maybe monad is perhaps one of the simplest examples of a monad available. It's also quite useful. The Maybe monad provides an elegant solution to the common problem of multiple nested null checks in code. Consider the following trivial example: var person = { "city":"Springfield" } }; if (person != null && person["address"] != null) { var state = Maybe(person["address"]["state"]); if (state != Nothing) { bind: function(fn) { return this; } }; var Something = function(value) { "address": { return true; }; }; if (typeof value === 'undefined' || value === null) return def; } do { f x } = do { v < m; return v } do { f x } = do { y < do { x < m; y < f x; g y } = do { v < return x; f v } }; }; if (typeof value === 'undefined' || value === null) return (x, 42) is transformed during compilation into: a = [3..4] >>= (\x -> [1..2] >>= (\_ -> return (x, 42))) It is helpful to see the implementation of the list monad, and to know that concatMap maps a function over a list and concatenates (flattens) the resulting lists: instance Monad [] where m >>= f = concat (map f m) return x = [x] fail s = [] concatMap f = concat . map f Therefore, the following transformations hold and all the following expressions are equivalent: a = [3..4] >>= (\x -> [1..2] >>= (\_ -> return (x, 42))) a = [3..4] >>= (\x -> [(x,42),(x,42)] ) a = concatMap (\x -> [(x,42),(x,42)] ) [3..4] a = [(3,42),(3,42),(4,42),(4,42)] Notice that the values in the list [1..2] are not used. The lack of a left-pointing arrow, translated into a binding to a function that ignores its argument, indicates that only the monadic structure is of interest, not the values inside it, e.g. for a state monad this might be used for changing the state without producing any more result values. The do-block notation can be used with any monad as it is simply syntactic sugar for >>=. A similar example in F# using a computation expression: let readNum () = let s = Console.ReadLine() let succ,v = Int32.TryParse(s) if (succ) then Some(v) else None let secure_div = maybe { A type constructor that defines, for every underlying type, how to obtain a corresponding monadic type. In Haskell's notation, the name of the monad represents the type constructor. If M is the name of the monad and t is a data type, then M t is the corresponding type in the monad. A monad is created by defining a type constructor M and two operations, bind and return (where return is often also called unit): The binary bind operation ">>=" takes as its arguments a monadic value M a and a function (a ° M b) that can transform the value. The binary bind operation ">>=" takes as its arguments a monadic value M a and a function (a ° M b) that can transform the value. The bind operator unwraps the plain value a embedded in its input monadic value M a, and feeds it to the function. bind: function(fn) { A unit function that injects a value in an underlying type to a value in the monad that has only monad-related structure and no values from the underlying type. In the Maybe monad, "Nothing" is a zero. In the List monad, "[]" (the empty list) is a zero. Syntactic sugar: do-notation Although there are times when it makes sense to use the bind operator >>= directly in a program, it is more typical to use a format called do-notation (perform-notation in OCaml, computation expressions in F#), that mimics the appearance of imperative languages. The compiler translates do-notation to expressions involving >>=. For example, both following definitions for safe division for values in the Maybe monad are equivalent: x // y = do a < x -- Extract the values "inside" x and y, if there are any. b < y if b == 0 then Nothing else Just (a / b) x // y = x >>= (\a -> y >>= (\b -> if b == 0 then Nothing else Just (a / b) x // y = x >>= (\a -> y >>= (\b -> if b == 0 then Nothing else Just (a / b) x // y = x >>= (\a -> y >>= (\b -> if b == 0 then Nothing else Just (a / b) x // y = x >>= (\a -> y >>= (\b -> if b == 0 then Nothing else Just (a / b) x // y = x >>= (\a -> y >>= (\b -> if b == 0 then Nothing else Just (a / b) x // y = x >>= (\a -> y >>= (\b -> if b == 0 then Nothing else Just (a / b) x // y = x >>= (\a -> y >>= (\b -> if b == 0 then Nothing else Just (a / b) x // y = x >>= (\a -> y >>= (\b -> if b == 0 then Nothing else Just (a / b) x // y = x >>= (\a -> y >>= (\b -> if b == 0 then Nothing else Just (a / b) x // y = x >>= (\a -> y >>= (\b -> if b == 0 then Nothing else Just (a / b) x // y = x >>= (\a -> y >>= (\b -> if b == 0 then Nothing else Just (a / b))) As another example, the following code: a = do x < [3..4] val: function() { return value; bind: function(fn) { }, if (y = 0) }, val: function() { m >>= return = m Binding two functions in succession is the same as binding one function that can be determined from them: return value; return true; return def; } }; var Something = function(value) { return def; } do { m } = do { v < return x; f v } }; }; if (typeof value === 'undefined' || value === null) return acts approximately as a neutral element of >>=, in that: "city":"Springfield" } }; if (person != null && person["address"] != null) { return value; 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 for you. In this way, you don't have to keep writing loops all over the place when dealing with multiple results. The bind function "automatically" does all that for you. (The List Monad.) Extending this idea, you can implement "exceptions". (The Error Monad or Exception Monad.) Because you're defining them yourself rather than it being a language feature, you can define how they work. (E.g., maybe you want to ignore the first two exceptions and only abort when a third exception is thrown.) You can implement "continuations" as a monad. This allows you to simulate destructive updates, without actually doing destructive updates. (The State Monad and its cousin the Writer Monad.) You can make a monad where calculations can be paused, so you can pause your program, go in and tinker with internal state data, and then resume it. You can implement "continuations" as a monad. This allows you to simulate destructive updates, without actually doing destructive updates. (The State Monad and its cousin the Writer Monad.) Extending this idea, you can implement "exceptions". (The Error Monad or Exception Monad.) Because you're defining them yourself rather than it being a language feature, you can define how they work. (E.g., maybe you want to ignore the first two exceptions and only abort when a third exception is thrown.) You can make each step return multiple results, and have the bind function loop over them, feeding each one into the next step for you. In this way, you don't have to keep writing loops all over the place when dealing with multiple results. The bind function "automatically" does all that for you. (The List Monad.) Because you're only simulating destructive updates, you can trivially do things that would be impossible with real destructive updates. For example, you can undo the last update, or revert to an older version. You can implement "continuations" as a monad. This allows you to break people's minds!