### A simple introduction to why Monads are useful

The operations that define the monad must fulfil several properties to allow the correct composition of monadic functions (i.e. functions that use values from the monad as their arguments or return value). Because a monad can insert additional operations around a program's domain logic, monads can be considered a sort of aspect-oriented programming.[8] The domain logic can be defined by the application programmer in the pipeline, while required aside bookkeeping operations can be handled by a pre-defined monad built in advance. In a purely functional language, such as Haskell, functions cannot have any externally visible side effects as part of the function semantics. Although a function cannot directly cause a side effect, it can construct a value describing a desired side effect, that the caller should apply at a convenient time.[10] In the Haskell notation, a value of type M b. Monad laws For a monad to behave correctly, the definitions must obey a few axioms, together called the monad laws.[11] The = symbol indicates equivalence between two Haskell expressions in the following text. return Nothing; return Something(value); }; isNothing() and val() The isNothing and val functions are rather self-explanatory. The isNothing function returns true if the Maybe is Nothing then val will throw an error. We don't require these methods for our example (or even for Maybe to be a monad), but they often prove useful elsewhere. maybe(def, fn) The maybe function is the most useful for our purposes, and is identical to the maybe function for Haskell's Maybe monad. It takes a default value (def) and a function fn and if the Maybe is Nothing then val will throw an error. We don't require these methods for our example (or even for Maybe to be a monad), but they often prove useful elsewhere. maybe(def, fn) The maybe function is the most useful for our purposes, and is identical to the maybe function for Haskell's Maybe monad. It takes a default value (def) and a function fn and if the Maybe is Nothing and false otherwise. The val function simply returns the value inside the Maybe monad if it is "something," similar to Haskell's fromJust function. If the Maybe is Nothing and false otherwise. The val function simply returns the value inside the Maybe monad if it is "something," similar to Haskell's fromJust function. If the Maybe is Nothing and false otherwise. The val function simply returns the value inside the Maybe monad if it is "something," similar to Haskell's fromJust function. If the Maybe is Nothing and false otherwise. The val function simply returns the value inside the Maybe monad if it is "something," similar to Haskell's fromJust function. If the Maybe is Nothing then val will throw an error. We don't require these methods for our example (or even for Maybe to be a monad), but they often prove useful elsewhere. maybe(def, fn) The maybe function is the most useful for our purposes, and is identical to the maybe function for Haskell's Maybe monad. It takes a default value (def) and a function fn and if the Maybe is Nothing, returns the default value, otherwise it applies the function to the contents of the Maybe and returns the result. We can use this handy function to rid ourselves of the final if ... else statement in our example: console.log(Maybe(person).bind(function(p) { return p["address"]; }).bind(function(a) { return a["state"]; }); if (state == Nothing) { console.log("State unknown"); } else { console.log(state); } Certainly this is better than before, but can we do better? (Note: If you're keeping score, then you'll note the type signature of our bind differs from Haskell's >>=. Haskell's bind operator is of type m a -> (a -> m b) -> m b, whereas ours is m a -> (a -> m b) -> m b, whereas ours is m a -> (a -> m b) -> m b, whereas ours is m a -> (a -> m b) -> m b, whereas ours is m a -> (a -> m b) -> m b, whereas ours is m a -> (a -> b) -> m b. That is, 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 function application. Since Nothing has no value, anything bound to a Nothing should simply return Nothing (our short-circuit). Maybe = function(value) { var Nothing = { bind: function(fn) { then None else { }, val: function() { m >>= return = m Binding two functions in succession is the same as binding one function that can be determined from them: The binary bind operation ">>=" takes as its arguments a monadic value M a and a function (a ° M b) that can transform the value. val: function() { "address": { (m >>= f) >>= g = m >>= ( \x -> (f x >>= g) ) The axioms can also be expressed using expressions in do-block style: do { f x } = do { v < return x; f v } do { f x } = do { v < return x; f v } do { f x } = do { y < do { x < m; f x }; g y } or using the monadic composition operator, (f >=> g) x = (f x) >>= g: return Nothing; return Something(value); }; With this new bind method we can more elegantly re-write our code: var state = Maybe(person).bind(function(p) { return p["address"]; }).bind(function(a) { return a["state"]; }); if (state == Nothing) { console.log("State unknown"); } else { console.log(state); } Certainly this is better than before, but can we do better? (Note: If you're keeping score, then you'll note the type signature of our bind differs from Haskell's >>=. Haskell's bind operator is of type m a -> (a -> b) -> m b. That is, we should pass in a function fn that returns a non-monadic - non-Maybe - value. I do this because JavaScript's type system is, understatedly, quite weak, so I prefer to enforce the wrapping of the function's return value 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))) As another example, the following code: a = do x < [3..4] = join . join join . fmap return = join . join join . fmap return = join . return = id join . fmap (fmap f) = fmap f . join The first two laws correspond to the monad axioms, while the third states that join is a natural transformation from the identity "id" to "fmap". In addition, the join function characterizes monads: join . fmap join 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 pass in a function fn that returns a non-monadic - non-Maybe - value. I do this because JavaScript's type system is, understatedly, quite weak, so I prefer to enforce the wrapping of the function's return value in the Maybe monad myself. You can of course elect not to do this, and instead ensure that any function you pass to bind always returns a Maybe.)