
You are absolutely right. The statement "The values of the IO monad are programs that do IO. " is somewhat nonsensical. Values don't do anything, they just are. But values of the IO monad *describe* how to do IO; they can be seen as a recipe for doing IO. A recipe doesn't cook a dish, but when the recipe is executed by a cook they creates a dish. An IO values doesn't do IO, but when it is executed by the runtime system IO happens.
Just as a recipe describes how to cook something, a program describes how to accomplish something. The program doesnt "do" anything until it is executed. However, we often use the word "do" to describe what a program will do when executed (even though its really the cpu that is actually "doing").
This is one way of interpreting what the IO type means. (Another one is to say that Haskell is just an imperative programming language, but any imperative actions show up in the type.)
I don't see the difference between these two interpretations. Wether the program is made up of instructions for a cpu or for an interpreter seems irrelevant.
-- Lennart
Tim Newsham http://www.thenewsh.com/~newsham/