I want to make sure that I'm understanding this bit correctly:
>A better metaphor is to think of values of type IO a as fragments of a script in some other (imperative) language. The Haskell program merely computes the script, and the runtime then takes care of actually executing it. In this sense, effects in Haskell are not "side" -- they are first class citizens. What order the fragments of the imperative program are computed in (or how many times) is independent of the text of the final program.
In Wadler's paper, the monadic output example looks like this:
type M a = (Output, a)
type Output = String
unit :: a → M a
unit a = (“ ”, a)
(*) :: M a → (a → M b) → M b
m * k = let(x, a) = m in
let(y, b) = k a in
(x ++ y, b)
out :: Output → M ()
out x = (x, ())
where each function, instead of returning a simple numeric value, returns a tuple of a string (the output to be printed) and a number (the value to be returned). If you wrote this function out in Haskell, you would have access the output text in the form of a lazy list of strings.If we can think of IO values as fragments of an imperative script that are handled at runtime, then that makes me think that the Haskell compiler doesn't use the strategy presented in Wadler's paper (in the case of printing output, returning a lazy list of strings to be printed), and instead just performs the specified side effects directly, knowing that semantics of the IO monad guarantee that things will be sequenced correctly. Do I have this right?