Last time in this series we finally worked out the actual rules for the monad pattern. The pattern in C# is that a monad is a generic type `M<T>`

that “amplifies” the power of a type `T`

. There is always a way to construct an `M<T>`

from a value of `T`

, which we characterized as the existence of a helper method:

static M<T> CreateSimpleM<T>(T t)

And if you have a function that takes any type `A`

and produces an `M<R>`

then there is a way to apply that function to an instance of `M<A>`

in a way that still produces an `M<R>`

. We characterized this as the existence of a helper method:

static M<R> ApplySpecialFunction<A, R>( M<A> wrapped, Func<A, M<R>> function)

Is that it? Not quite. In order to actually be a valid implementation of the monad pattern, these two helper methods need to have a few additional restrictions placed on them, to ensure that they are well-behaved. Specifically: the construction helper function can be thought of as “wrapping up” a value, and the application helper function knows how to “unwrap” a value; it seems reasonable that **we require that wrapping and unwrapping operations preserve the value**.