Thanks for all the help. The simplified example indeed threw away too
much. There were no side effects.
Brent, of course I couldn't create your function; though I gained
through trying. I then found it useful to consider the type of:
fmap (\x -> putStrLn x) getLine
which is IO (IO ()) and hence displays nothing to the screen.
Felipe, your recursive example was also compelling and concise.
Antoine, I see how the join capacity of a Monad can be useful in this
issue. I'm also reminded of what <*> can bring to fmap/<$>.
On reflection, I often trip up when learning by comparing IO to simpler
monads such as [] and Maybe. But [] and Maybe never have effects, and so
are poor foils. The ((->) t) monad is henceforth in my toolbox.
Paul