This is not true. The arguments for `next` include both:
* The target stream.
* A "state token" or universe.
You get different results with different state tokens.
At a high level, the thing to consider is that we can model all imperative programming with functional programming -- we can model Turing Machines with Lambda Calculus -- as well as go the other way around, because Turing Machines and the Lambda Calculus are, for all intents and purposes, equivalently expressive.
Modeling IO with state monads isn't a hack; it's the point.
Can you replay a get from stream by passing in an older token?
Monads provide a way to combine them and a way to inject values into them; but not all monads provide the inspection interface that would allow you to examine that state token. The definition of a monad guarantees only the injection and the combination (the "unit" and "multiply").
next :: Stream a -> IO a
The function part is pure. The `execution` of the resulting `IO a` action (which is completely separate from its pure evaluation) is not.