Johannes Waldmann <joe@isun.informatik.uni-leipzig.de> wrote,
However, I would move IO further to the front. For any "real life" programming, IO is essential...
I am currently teaching a Functional Programming lecture (notes in German: http://www.informatik.uni-leipzig.de/~joe/edu/ws00/praxis/skript/) and I also used this approach: use the do-notation intuitively (for text IO and graphics, using SOE book), and explain monads later (with parser combinators and interpreters).
This could be driven to the extreme: not only hide the word "monad", but also "functional". The title would be "Imperative programming in Haskell" (as S. Peyton Jones says in Tackling the Awkward Squad: "Haskell is the world's finest imperative programming language").
The students would start writing do-notated programs in the IO monad, starting with putStrLn "Hello World"; and gradually the emphasis is shifted from sequencing (the "semicolon") to "what can we do on the righthand side of let x = ... ", thus introducing functional programming.
Starting with putStrLn "Hello World" is a good idea and this would exactly be my approach when teaching students who already know some programming language (in the course I did last term, it was their first programming experience; therefore, I waited until Week 5). However, I don't think it is necessary (or desirable) to hide "functional". With "monad" it is a different story, as it is a complicated sounding word, which is not easily explained (to non-mathematicians). And it is not necessary; we are not starting on fixed point and domain theory either when explaining recursive functions. Actually, I did run a moderately detailed survey at the end about what the students found interesting/boring and difficult/easy etc (and with a good sample size, too: close to 500 students filled in the survey). I am planing to summarise the results and post them here sometime. Cheers, Manuel