{-+ An IO wrapper monad for redirecting Stdio. -} module SIO(SIO,StdIOops(..),runSIO,withStdio,inBase) where import Prelude hiding (getContents,readFile,writeFile,ioError,catch,putStr) import AbstractIO as A import EnvMT as E import MT(HasBaseMonad(..),HasEnv(..),Z) import MUtils newtype SIO a = SIO (WithEnv StdIOops IO a) deriving (Functor,Monad,FileIO,SystemIO,DirectoryIO,TimeIO) data StdIOops = StdIO {put,eput::String->IO (){-, get::IO String-}} runSIO (SIO m) = withEnv stdIOops m where stdIOops = StdIO { put=putStr,eput=ePutStr{-,get=getContents-}} withStdio ops = E.inEnv (ops::StdIOops) instance HasEnv SIO Z StdIOops where getEnv ix = SIO E.getEnv inEnv _ e (SIO m) = SIO (E.inEnv e m) --instance HasBaseMonad IO IO where inBase = id instance HasBaseMonad SIO IO where inBase io = SIO $ lift io stdPut s = do put <- put # E.getEnv inBase (put s) stdePut s = do put <- eput # E.getEnv inBase (put s) {- stdGet = do get <- get # E.getEnv inBase get -} instance StdIO SIO where putStr = stdPut ePutStr = stdePut getContents = inBase getContents instance CatchIO IOError SIO where SIO m1 `catch` em2 = SIO $ m1 `catch` \ e -> let SIO m2 = em2 e in m2 ioError = SIO . ioError instance CatchIO err m => CatchIO err (WithEnv e m) where m `catch` f = do e <- E.getEnv lift (withEnv e m `catch` (withEnv e . f)) ioError = lift . ioError