The IO monad in Haskell is often explained as a state monad where the state is the world. So a value of type IO a monad is viewed as something like worldState -> (a, worldState).Some time ago I read an article (or a blog/mailing list post) that criticized this view and gave several reasons why it's not correct. But I cannot remember neither the article nor the reasons. Anybody knows?Edit: The article seems lost, so let's start gathering various arguments here.I'm starting a bounty to make things more interesting.Edit: The article I was looking for is Tackling the awkward squad: monadic input/output, concurrency, exceptions, and foreign-language calls in Haskell by Simon Peyton Jones. (Thanks to TacTics's answer.)
Critique of the IO monad being viewed as a state monad operating on the world
functional programming;haskell;io;monad
The problem with IO a = worldState -> (a, worldState) is that if this were true then we could prove that forever (putStrLn Hello) :: IO a and undefined :: IO a are equal.  Here is the proof courtesy of dolio (2010, irc):forever m =m >> forever m =fix (\r -> m >> r) = {definition of >> for worldState -> (a, worldState)}fix (\r -> \w -> r (snd $ m w))Lemma: (\r w -> r (snd $ m w))  = (\r w -> r (snd $ m w))   =\w ->  (snd $ m w))  = . snd . m  =Therefore forever m = fix (\r -> \w -> r (snd $ m w)) = In particular forever (putStrLn Hello) =  and hence forever (putStrLn Hello) and undefined are equivalent programs.  However, clearly they are not supposed to be considered equivalent programs, in theory or in practice.Notice that this model is wrong even without invoking concurrency.