User:HowardBGolden/Sandbox/Haskell/Understanding monads

Since Haskell is a "pure" (i.e., without side-effects) functional language, it wasn't obvious how to introduce input and output (which are clearly side-effects on the world) into the language and still maintain its purity. In 1991, Eugenio Moggi proposed using a concept called "monads" from category theory, a branch of mathematics, to make this possible. It quickly became apparent that the monad concept had many additional benefits to Haskell besides solving the purity vs. input/output conundrum and the concept became deeply embedded in the language and its usage. Since category theory is unfamiliar to most people coming to Haskell, there is a need to explain what monads are and how monads are used in Haskell.

Monads are very useful in Haskell, but the concept is often difficult for newcomers to grasp. Once a person understands the concept, there is often a desire to help others understand it as well. This has led to an explosion of monad tutorials, usually accompanied by various analogies of monads to familiar concepts. The variety of explanations and analogies may actually make it harder for the newcomer to learn rather than easier.

This chapter discusses the monad concept as it particularly applies to Haskell. It isn't intended to be an introduction to category theory.

Historical motivation
Eugenio Moggi's work introduced the monad concept into Haskell to allow input/output while still maintaining the language's purity. In essence, the pure and impure (input/output or other side-effects) are separated from each other using Haskell's strong type system. Every program starts out in the  function which has the type. is a Haskell type which is a monad (or, in equivalent terms, the  type is an instance of the   type class). Code within a function with the  type can execute input/output functions. However, code in a function with any other type cannot execute input/output functions. Any attempt to execute input/output functions inside functions not of  type will be blocked as a type error by Haskell's type system.