If I were in charge of developing a safety critical system, and someone came to me with a proposal to write it in Haskell, I'd be very skeptical.
Structural recursion can't be guaranteed to terminate in any language that supports codata unless you have some sort of totality checker (e.g. via a monotonically structurally decreasing requirement imposed at the type or value level). I don't think any mainstream language supports this out of the box. Liquid Haskell does offer this, though.
I agree that standard Haskell is inappropriate for safety critical software, but only because it allows dynamic allocation. Any program using dynamic allocation is probably unsuitable for safety critical software. Now, a terminating and fixed-memory subset of Haskell a la Clash would be interesting for safety critical software...
Structural recursion always terminates in SML. Supporting infinite/cyclic values in algebraic data types is a misfeature, and they are trivial to rule out without using a totality checker. Heck, I can implement a guaranteed finite linked list in Java :-)
I think something like MLKit would be a more promising start for implementing a safety critical system. Tail and structural recursion actually work there, and it statically replaces most uses of GC with region inference. Though it's still a very long shot, I'd prefer something more proven.
Interesting fact about foldl'. Regardless, in practice it is strict and tail recursive. As I mentioned earlier, this does not mean the same thing as constant space unless the reduction function returns a fixed size result.
Yes, you can guarantee that a linked list in Java is finite because Java does not support codata.
Haskell's tail call recursion is also often optimized to be allocation-free, unless, again, it is generating some data structure.
Definitely.
I something think Haskell should treat non-terminating code the same way they treat IO: only allow it in portions of the code-base that are tagged somehow.
If there's something that doesn't cause a side-effect, but the compiler doesn't know that, you can tell it with unsafePerformIO. If there's something that terminates, but the compiler doesn't know, (eg calculating the hailstone sequence for a number), there could also be a suitable escape hatch to be used with care.