| Two glaring errors in here: > The essence of monads is to use abstract types to enclose a mutable state [...] This is a common misconception, but terribly misleading. The "essence" of monads are the bind and return (or equivalent) functions, allowing decoupled transformations to be performed. The fact that you can write bind and return functions for a type that encapsulates the idea of a side effect is secondary. Would you say "the essence of iterators is to encapsulate infinite sequences"? Infinite sequences happen to be iterable, but to say that they are the essence of iterators is downright wrong. The essence of iterators is traveling through a collection item by item, as defined by the MoveNext/Current (or equivalent) functions. > For one thing, when you use a monad, you get hooked to it: the type constructors of the monad start to appear in the signatures of your function. If you have functions that should have nothing to do with a monad ending up coupled to it, then you're probably doing it wrong. Monadic methods let you "lift" functions, so they don't have to be coupled: // bad: unnecessarily coupling your function to a monad
IEnumerable<int> Increment(IEnumerable<int> sequence) {
var r = new List<int>();
foreach (var e in sequence) r.Add(e + 1);
return r;
}
...
var incrementedList = Increment(list);
// good: using monad method to lift a non-coupled function
int Increment(int b) { return b + 1; }
var incrementedList = list.Map(Increment);
|
> But mutable state covers everything that is not pure computation and that includes debug statements, input and output, system calls, network access, getting the time of the day or even throwing an exception. So the monad you are using has to provide all these services. Of course not every monad has everything you need so you have the IO monad, the Maybe monad, the STM monad, and so on. Whenever you have a C binding, you get a monad.
The second point example doesn't seem to address the author's concerns. The author is complaining about what happens when you try to compose N components that all disagree on the model of computation. OCaml has a more practical default model of computation so less such plumbing is needed.