To clarify the question: it is about the merits of the monad type class (as opposed to just its instances without the unifying class).
After having read many references (see below), I came to the conclusion that, actually, the monad class is there to solve only one, but big and crucial, problem: the 'chaining' of functions on types with context. Hence, the famous sentence "monads are programmable semicolons". In fact, a monad can be viewed as an array of functions with helper operations.
I insist on the difference between the monad class, understood as a general interface for other types; and these other types instantiating the class (thus, "monadic types").
I understand that the monad class by itself, only solves the chaining of operators because mainly, it only mandates its type instances
to have bind >>=
and return
, and tell us how they must behave. And as a bonus, the compiler greatyly helps the coding providing do
notation for monadic types.
On the other hand,
it is each individual type instantiating the monad class which solves each concrete problem, but not merely for being a instance of Monad. For instance Maybe
solves "how a function returns a value or an error", State
solves "how to have functions with global state", IO
solves "how to interact with the outside world", and so on. All theses classes encapsulate a value within a context.
But soon or later, we will need to chain operations on such context-types. I.e., we will need to organize calls to functions on these types in a particular sequence (for an example of such a problem, please read the example about multivalued functions in You could have invented monads).
And you get solved the problem of chaining, if you have each type be an instance of the monad class.
For the chaining to work you need >>=
just with the exact signature it has, no other. (See this question).
Therefore, I guess that the next time you define a context data type T for solving something, if you need to sequence calls of functions (on values of T) consider making T an instance of Monad
(if you need "chaining with choice" and if you can benefit from the do
notation). And to make sure you are doing it right, check that T satisfies the monad laws
Then, I ask two questions to the Haskell experts:
- A concrete question: is there any other problem that the monad class solves by ifself (leaving apart monadic classes)? If any, then, how it compares in relevance to the problem of chaining operations?
- An optional general question: are my conclusions right, am I misunderstanding something?
References
Tutorials
- Monads in pictures Definitely worth it; read this one first.
- Fistful of monads
- You could have invented monads
- Monads are trees (pdf)