### A simple introduction to why Monads are useful

Although Haskell defines monads in terms of the return and bind functions, it is also possible to define a monad in terms of return and two other operations, join and fmap. This formulation fits more closely with the original definition of monads in category theory. The fmap operation, with type (t°u ) ° M t°M u,[12] takes a function between two types and produces a function that does the "same thing" to values in the monad. The join operation, with type M (M t)°M t, "flattens" two layers of monadic information into one. The two formulations are related as follows: fmap f m = m >>= (return . f) join n = n >>= id m >>= g = join (fmap g m) Here, m has the type M t, n has the type M t, n has the type M (M r), f 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 = a + (b + c) m + m0 = a + (b + c) m + m0 The unary return operation takes a value from a plain type and puts it into a container using the constructor, creating a monadic value: M a. 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 (typeof value === 'undefined' || value === null) return { return >=> g = g f >=> return = f (f >=> g) >=> h = f >=> (g >=> h) fmap and join Although Haskell defines monads in terms of the return and bind functions, it is also possible to define a monad in terms of return and two other operations, join and fmap. This formulation fits more closely with the original definition of monads in category theory. The fmap operation, with type (t°u ) ° M t°M u,[12] takes a function between two types and produces a function that does the "same thing" to values in the monad. The join operation, with type M (M t)°M t, "flattens" two layers of monadic information into one. The two formulations are related as follows: fmap f m = m >>= (return . f) join n = n >>= id m >>= g = id fmap (f . g) = m m0 + m [1..2] if (y=0) then None else maybe.Return(x / y)))) Generic monadic functions Given values produced by safe division, we might want to carry on doing calculations without having to check manually if they are Nothing (i.e. resulted from an attempted division by zero). We can do this using a "lifting" function, which we can define not only for Maybe but for arbitrary monads. In Haskell this is called liftM2: liftM2 :: Monad m => (a -> b -> c) -> m a -> m b -> m c liftM2 op mx my = do x <- mx y<- my 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 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 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 -> 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] 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 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.