
Am 05.11.18 um 23:27 schrieb Brandon Allbery:
No state is modified, at least in ghc's implementation of IO.
That's what I'd expect.
IO does carry "state" around, but never modifies it; it exists solely to establish a data dependency (passed to and returned from all IO actions; think s -> (a, s), In Haskell, a data dependency can impose constraints on evaluation order, but it isn't always linear: which subexpression is evaluated first depends on what a pattern match requests (at least in Haskell: Haskell's strict operation is the pattern match).
The ordering constraint becomes linear if each function calls just a single other function. I'm not sure that that's what happens with IO; input operations must allow choices and loops, making me wonder how linearity is established. It also makes me wonder how an IO expression would look like if fully evaluated; is it an infinite data structure, made useful only through Haskell's laziness, or is it something that's happening in the runtime? The other thing that's confusing me is that I don't see anything that starts the IO processing. There's no pattern match that triggers an evaluation. Not that this would explain much: If IO were constructed in a way that a pattern match starts IO execution, there'd still be the question what starts this first pattern match. Then there's the open question what happens if a program has two IO expressions. How does the runtime know which one to execute? Forgive me for my basic questions; I have tried to understand Haskell, but I never got the opportunity to really use it so I cannot easily test my hypotheses. Regards, Jo