| I don't know how else to put it, but at least half of what you have written above is completely wrong. > but they're less useful in other languages where you already have effects everywhere. Scala has side effects everywhere, yet the Monad is extensively used in Scala programs. Monads have nothing to do with "effects". Monads are not used to decide the kind of "effects" you are allowed. By calling every Monad a kind of "effect", you are just begging the question. Monads are merely objects that follow 3 monad laws, no more no less. > This is why Haskell is pure despite having effects. Haskell programs don't do IO, they yield control to the runtime environment whenever IO needs to be done. How is this different from a C program? Haskell is pure in the presence of IO, because the type system tracks IO calls and forces any function that even indirectly refers to a quantity obtained via IO to modify its type signature to reflect the IO action. This can be done with/without Monads. Haskell IO is a Monad, because it pretty much analogous to the State Monad and Haskell has special Monad syntax that lets you pass the World State implicitly and write imperative code in an imperative style. |
Monadic combinators are really just kind of type-sugar. Think: any ordering of computations can be expressed as a tree. However, the only ordering trees a pure-functional language must obey are call-trees (the parameters of a function must be computed before the results of a function, even after lazy-evaluation is taken into account). Monadic programming is a way to transform arbitrary ordering trees of possibly-dynamic depth and width into call trees while preserving the original ordering.
The really neat thing about monads is that they statically guarantee they'll preserve the original ordering, despite its being of dynamic width and depth.