The way I like to picture the IO monad is you don't have direct access to the values coming from IO. You can only give the monad some functions which it applies to the values. Among these functions there are some that tell the monad to send values back out (print to screen, send request, etc.). Basically, all these functions make your program.