- Easy wrapping to create new types: Ever switched the arguments of `mv` in your terminal (strings)? Read the User ID as an account balance (ints)? You can distinguish these statically, and it's easy to do so. (You can of course write a wrapper class in C++ around Int as well a la "class OtherInt { int value; int get(); set(int i) }", but how often do you do that?
- No IO in a type? It cannot do IO. Has "Monad" in the type? It can do Monadic stuff, but no operations specific to any Monad instance (such as Maybe, IO, ...).
- Types are forced documentation. Don't get me wrong, no documentation is as awful in Haskell as it is anywhere else. However, even without any ordinary comment, a type can give away a lot of what a function does; maybe even more importantly, it tells you what it cannot do. If you see something of type `(a -> b) -> (a -> a)`, you know that the first argument cannot possibly be used - it has to be a dummy parameter.
This is of course not counting the occasional comment explaining why/how you're doing something convoluted.
Oh yes but there is! It's called Haddock. It's widely (and probably exclusively) used. The entirety of the documetation you can find on Hackage [1] (example: [2]) is generated using it. The user guide can be found here [3].
[1]: http://hackage.haskell.org/ [2]: http://hackage.haskell.org/package/pipes-4.1.0/docs/Pipes-Pr... [3]: http://www.haskell.org/haddock/doc/html/