I think this works quite well with IO in Haskell. Most of my code is pure, but the parts which are really not, say OpenGL code, is all marked as such with IO in their type signatures.

Also, the STM monad is the most carefree way of dealing with concurrency I have found.