a thing that I think a lot of people don't quite get about Haskell is that it's actually not lazy evaluation that's the interesting thing about Haskell, but rather that in Haskell evaluation order doesn't matter1.
In other words, evaluation order becomes an implementation detail that you don't really need to care about. In most programming languages, the order in which things are evaluated changes the order in which side effects are run, but in Haskell that is not the case. That means that the compiler can freely reorder evaluation order and your program outwardly behaves in the exact same way because the order of side effects is completely decoupled from the order of evaluation.
This is easier and slightly well-better behaved in a lazy language like Haskell, but laziness is (in my opinion) not really the key or essential take-away from Haskell. Rather, the key innovation is making evaluation order a concern of the runtime rather than a concern of the programmer.
-
Modulo infinite loops, a.k.a. "bottoms"