> Lazy evaluation is a big risk, if you aren't writing programs that start and finish.
No it is not. I've been writing Haskell full-time for five and a half years and I can count on one hand the number of times that lazy evaluation has been a significant problem.
> At the line-by-line level, purely functional code also takes more effort to edit, once written, than imperative code.
This couldn't be further from the truth. Haskell's ease of maintenance is vastly better than every other language I've used because of purity and its much more advanced type system. I've had a colleague make a highly non-trivial sweeping change to a 2500 line application I had written that they had not worked with before and their change worked literally the first time they got it to compile. This is not one of those statements of "if it compiles, it works", which are obvious hyperbole to make a point. It's an actual experience I've had that happened exactly that way. My coworker and I were rather surprised and we both agreed that there's no way that could have happened in any other language in mainstream use today. It's actually still in our commit log with the description "Godly refactoring".
Refactorings in Haskell are relatively safe because you tend to be forced to acknowledge changes in a type or function's behavior at every place it's used. For example, if you add a field to a datatype, every pattern binding will have to recognize that fact. But for every place where that's the case in Haskell, you can accomplish the same thing in other languages. For example, if you add a field to a struct in C, you can rename its other fields, and then fix up every usage in your program. Other tricks include renaming a function you've changed, adding a dummy parameter, and of course, putting something in a wrapper type while you do the refactoring.
Haskell's type system (assuming you mean with GHC extensions because you called it advanced) only gives you an advantage in cases where other languages would have to resort to reflection or dynamic casts, i.e. specifically where they give up type safety and you'd miss a recompilation. In reasonable languages with generics, like C#, this is quite rare. For example, once in a while, in C#, you might wish you had associated types (or functional dependencies).
No it is not. I've been writing Haskell full-time for five and a half years and I can count on one hand the number of times that lazy evaluation has been a significant problem.
> At the line-by-line level, purely functional code also takes more effort to edit, once written, than imperative code.
This couldn't be further from the truth. Haskell's ease of maintenance is vastly better than every other language I've used because of purity and its much more advanced type system. I've had a colleague make a highly non-trivial sweeping change to a 2500 line application I had written that they had not worked with before and their change worked literally the first time they got it to compile. This is not one of those statements of "if it compiles, it works", which are obvious hyperbole to make a point. It's an actual experience I've had that happened exactly that way. My coworker and I were rather surprised and we both agreed that there's no way that could have happened in any other language in mainstream use today. It's actually still in our commit log with the description "Godly refactoring".