A general purpose, environment + IO monad (really, environment+exception+state) and the standard fare of operators over it:
(See Haskell 1.3 definition for what IO is capable of)
type EIO a b = a -> IO b (>>>) :: EIO a b -> EIO a c -> EIO c (>>>=) :: EIO a b -> (b -> EIO a c) -> EIO a c returnE :: a -> EIO b a getEnv :: EIO a a withEnv :: a -> EIO a b -> EIO a b ioe :: IO a -> EIO b a doEIO :: EIO a b -> a -> IO b failEWith :: IOError13 -> EIO a b handleE :: EIO a b -> (IOError13 -> EIO a b) -> EIO a b tryE :: EIO a b -> EIO a (Either IOError13 b) failE :: String -> EIO a b accumulateE :: [EIO a b] -> EIO a [b] sequenceE :: [EIO a b] -> EIO a ()