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.Monad

both :: (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.