Another trick Haskell uses is preferring abstractions that are based on concepts from CT[2], and validating the utility of those abstractions on their "rigorous mathematical foundations". This is again just another case of taking you to the math rather than the other way around. Programming languages are first and foremost human languages, meant to be written and read by humans. As such, their power is drawn from a single source: their interaction with human cognition. Whether an abstraction is "mathematical" (whatever that means) has absolutely no relevance to its power, which comes from cognition (and psychology in general) rather than math. All this "in your face" math does is make the machine's job of verifying your software easier.
A Haskeller tried convincing me that such a language is a good fit for human programmers, too, because all it is is a subset of more traditional, impure languages. But the notion of subset => simpler is a mathematical notion with no relevance to cognition. If humans operated in this way, natural languages would have been much more mathematically simpler, too.
[1]: See KeY: http://www.key-project.org/
[2]: To be fair, I'm not sure that Haskell, given its original design philosophy, has much choice in the matter.