There are far more precise, formal descriptions out there; however, I’ll give a practical, if imprecise, description of monads that I believe (!) makes them easier to think about:
A monad is a datatype1 that allows us to: represent computations2 that have some structured3 result, and chain such computations together4
- The datatype defines two operations, which (in Haskell parlance) are called bind (>>=) and return. return places a value in the monad, and bind is used to pass this monadic value to another function. Implementations of these operations must satisfy certain laws.
- Some expression to be evaluated.
- The result has some additional context. For example, that context could be that the computation may fail (Haskell’s Maybe monad), or that it is non-deterministic (List), or that some interaction with the outside-world occurs (IO).
- We can combine monadic values by passing them between functions that operate on them (using the bind operator)
Here’s an example in Haskell: