Actually, the IO monad in haskell desugars to
RealWorld -> (a, RealWorld)
Where RealWorld is a "token" that is just meant to be threaded through. You cannot create one yourself, so you have to be given one.
Thus, that function argument colors IO. Every PL feature is just an extension to System F.