Some examples and non-examples of monads.

# Examples

## Lists

Linked lists form what can be loosely thought of as a nondeterminism monad. In fact, join is simply concat and >>= is an infix version of concatMap.

## Functions

Functions from a fixed value form a monad. join can be used to pass the same argument to a function twice, while return is a synonym for const. I do not know of any interpretation of >>=, but note that fmap is (.).

As an example, we can define the following:

import Control.Arrow
import Control.Monadboth :: (a -> a) -> (a, a) -> (a, a)
both = join (***)

which is equivalent to

both :: (a -> a) -> (a, a) -> (a, a)
both f (x, y) = (f x, f y)

Note also that sequence can be used to apply a list of functions to a common value, as follows:

λ:> sequence [(+1), (+2)] 3
[4,5]

Finally, note that (<*>) allows us to split inputs to a function, as in the following:

idempotent :: Eq a => (a -> a) -> a -> Bool
idempotent = ((==) <*>)

which is equivalent to the slightly clearer

idempotent :: Eq a => (a -> a) -> a -> Bool
idempotent f x = x == f x

## IO

The IO monad is especially important because it allows relatively painless side-effecting computation in a lazy language. In Haskell, it is defined as follows:

newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #))

This is essentially a state monad with state type State# RealWorld.

# Non-Examples

## Tuples

Tuples are functorial, but not monadic. To see why this is the case, consider the type signature of a hypothetical monad instance:

join :: (a, (a, b)) -> (a, b)
join (x, (y, z)) = ???

Such a function would be immoral as it must either forget x or y with no reason to prefer one over the other. Worse, consider return:

return :: a -> (b, a)
return = ???

This would require undefined to work in general.

## Constant Functor

The constant functor is a functor, but not an applicative functor. A hypothetical applicative instance would have the following type signature:

(<*>) :: Constant a (b -> c) -> Constant a b -> Constant b c
(<*>) (Constant x) (Constant y) = ???

This would be immoral; similar problems arise for pure as above with return and tuples.