Hence I don't really see, "rigorous correctness" as a good selling point for using Haskell since company culture tends to affect correctness just as much as the language a team uses.
Hence I don't really see, "rigorous correctness" as a good selling point for using Haskell since company culture tends to affect correctness just as much as the language a team uses.
You can get halfway to Nirvana just by using a language that self-manages memory and has some kind of exception system (error handling at a distance); something like RAII (automatic lifecycle management, or automatic destructors in a pinch) can be a big help, too. Now, at least, all the systems-level boilerplate can be omitted from your mainline code.
But high level, business logic pitfalls are hard to encapsulate, and especially so in a dynamically typed program. Documentation becomes critically important (don't ever do X before you do Y), as rigorous unit tests for chains of actions can sometimes be difficult to write. A good, type-level model of your program can be a helpful set of safety rails when refactoring a a large and complex code base, and a rich type system gives you more tools to build those rails to fit the the solution you're building. As a (weak) example, if your type model never lets you read from a file that's already been closed, that's one less thing you have to cover in testing or documentation -- or more importantly, it's one less thing you have to remember to test.
At scale, having multiple ways to introduce structure into an otherwise chaotic (or arbitrarily structured) code base is a win. Building a good type-level model is one smart way to achieve that.
The added boilerplate usually translates to less readability and distracts from the "essence" of the problem or the main idea a piece of code is trying to communicate.