Jump to content

User:HowardBGolden/Sandbox/Haskell/Understanding monads

From Wikibooks, open books for an open world

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

[edit | edit source]

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 main function which has the type IO (). IO is a Haskell type which is a monad (or, in equivalent terms, the IO type is an instance of the Monad type class). Code within a function with the IO 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 IO type will be blocked as a type error by Haskell's type system.