When those things come from a stream of business problems, Haskell, I hate to say, is a poor tool, for just the reason you stated. You’ll always come across situations where mutating state would make an incremental change very easy (despite being “bad practice” for long-term complexity) but where having rigorously designed a functional system, that mutation or change is now painfully hard and requires significant refactoring.
Because business pressures utterly do not care about engineering properties of the backend system, except for high level summaries of basic properties like overall cost or reliability (metrics that functional programming vs other paradigms doesn’t have much impact on), you end up never being able to justify the upkeep and refactor-as-you-go workloads necessary for the functional implementation to not get bastardized into the exact same sort of spaghetti code mess you get with other languages.
In my experience, the types of errors, bugs and extensibility headaches in a business setting are not addressable with static typing, designs leveraging a type system, formal verification, or immutable design patterns. Those things are fine, not knocking them. It’s just that they cannot help you for dealing with reactive business problems. They don’t live up to the hype about it.
The problems are all about a sudden context change in which a previously valid set of behaviors, performance characteristics, whatever, is instantly rendered invalid because circumstances have suddenly changed, and you need to simply react to it and pray you’re successful enough that the system even lives to some magical future time when you can refactor.