This tutorial aims to give a thorough understanding of IO in Haskell without using Monad theory. Instead, there are copious examples, and a theoretical emphasis on types. My justification for this approach appears at the end of this document, in the section entitled Reflections.
Throughout the tutorial, there are lots of examples, and a few exercises (with solutions!). You are strongly encouraged to experiment with the examples, and attempt the exercises. You can download them, but you will learn even more if you retype them into your favourite Haskell editor.
All feedback is welcome: please email any comments to email@example.com