That's an interesting question, which in my head relates rather specifically to Haskell, as other (purely) functional languages do not elevate monads to so high an esteem.
Technically speaking, you need more than a functor to construct a monad. In Haskell, the Monad
type class derives from the Applicative
type class. The page Applicative functor - HaskellWiki summarizes quite nicely the relationship between Functor
, Applicative
, and Monad
. On the immediate technical side, being able to define certain functions (e.g. bind
) is not sufficient for your type to qualify for a monad; you also have to ensure that some additional identities hold (which I didn't verify for your example).
On the paradigm level, I currently have the impression that monads are particularly useful and respected in Haskell because the type system of the language is intentionally very rigid. As one consequence, mixing a debug println
into your code is quite non-trivial because of the side-effects, and in particular taints the type of the whole function with the IO
monad. Now monads have the cool advantage of being very explicit, and the rigid type system in Haskell ensures that you must use a monad if you want any side-effect, which allows you to reason quite a long way about the code without actually running it (unless you put everything in IO
, which many people actually do, sometimes for the valid reason of reducing code complexity). Hovewer, I have the impression that it's not necessarily or generally a Rackety way of seeing or doing things. In Racket, if I want to do a displayln
in my function, I just do it, and it doesn't need to influence the return type. That gives me weaker guarantees about my code, but is less intrusive in many subtle ways. This is, by the way, one of the main reasons why I dropped Haskell for Racket, and why I don't regret the move.
I hope people with more experience with Racket will chime in and give their opinion on the matter.
By the way, I am quite interested in Qi: A Functional, Flow-Oriented DSL which allows threading data through computation in ways which I find highly superior to monads. Qi looks a little bit like Arrows: A General Interface to Computation , but without the rigid type system burden. To me, one ultimate thing to do is to build Typed Qi, which should be possible, but probably highly non-trivial. Still, I find that Qi is a more Rackety way to thread computation than monads.