Description

replicateM 10000000 (randomIO >>= evaluate)

blows the stack because of "sequence".

I think it is important for Haskell programmers to be able to compose existing components without having to worry about the operational semantics of laziness, so it is important for GHC to specialize "sequence" calls to a tail-recursive one when a strict monad is in use.

What do you expect to happen here? You are asking GHC to build a big list. (Yes, it is then discarded, but the loop that produces the list doesn't know that.) How can we produce a big list? Something like this:

Doing that automatically would be hard, esp as you'd want to be sure that cost of the extra reverse was justified. Oh... the numbers are random so you don't need to reverse it. But do you expect the compiler to know that?

In short, I'm dubious that there's a simple, general optimsation that we are missing. I'd love to know one -- please show me.