SIO.hs

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

Plain-text version of SIO.hs | Valid HTML?