module FudgetIOMonad1 where import Prelude hiding (readFile,writeFile, putStr,putStrLn,getLine,readLn,print, catch,ioError) import AllFudgets as F import AbstractIO as A import DialogueIO as D import MUtils --import MT import PfePlumbing {-+ To avoid a problem with overlapping instances in the MT class, the types of the streams are hardwired... -} type PfeF = F In (Either String Out) newtype FIOM a = M {unM::(a->PfeF)->(D.IOError->PfeF)->PfeF} runFIOM (M m) = m (const end) (error.show) instance Functor FIOM where fmap f (M m) = M $ \ c h -> m (c.f) h instance Monad FIOM where return x = M $ \ c h -> c x M m1>>=xm2 = M $ \ c h -> m1 (\x->unM (xm2 x) c h) h fail s = M $ \ c h -> h (OtherError s) -------------------------------------------------------------------------------- getFM = M $ \ c h -> get c putFM x = M $ \ c h -> put x (c ()) quitFM = succIO (Exit 0) {- class Monad m => SPIO m where putM :: Out -> m () getM :: m In instance SPIO FIOM where putM = putFM getM = getFM instance (Monad (t m),MT t,SPIO m) => SPIO (t m) where putM = lift . putM getM = lift getM -} -------------------------------------------------------------------------------- instance FileIO FIOM where readFile = strIO . ReadFile writeFile path s = succIO (WriteFile path s) instance StdIO FIOM where putStr s = succIO (AppendChan "stdout" s) ePutStr s = succIO (AppendChan "stderr" s) instance CatchIO D.IOError FIOM where M m `catch` h = M $ \ c h' -> m c (\e->unM (h e) c h') ioError e = M $ \ _ h -> h e instance DirectoryIO FIOM where createDirectory path = succIO (CreateDirectory path "") removeFile = succIO . DeleteFile getDirectoryContents = strListIO . ReadDirectory doesDirectoryExist path = catchFalse $ (((==)"d").take 1) # statusFile path doesFileExist path = catchFalse $ (((==)"f").take 1) # statusFile path getModificationTime path = M $ flip (F.getModificationTime path) statusFile = strIO . StatusFile catchFalse io = io `catch` const (return False) instance SystemIO FIOM where --system cmd = succIO (System cmd) >> return ExitSuccess -- !! system cmd = M $ \ c h -> hIOerr (System cmd) (c.exitcode) (c.const ExitSuccess) where exitcode (OtherError s) = ExitFailure . read . last . words $ s exitcode _ = ExitFailure 99 -- hmm getEnv = strIO . GetEnv getProgName = return progName getArgs = return args -- Does not include options! instance TimeIO FIOM where getClockTime = xrequestFIOM getTime instance IOErr D.IOError where isDoesNotExistError (ReadError _) = True isDoesNotExistError _ = False ioeGetErrorString err = case err of OtherError s -> s _ -> show err -- hmm! userError = OtherError -- hmm! isUserError _ = False -------------------------------------------------------------------------------- strIO req = ansIO req (\(Str s)->s) strListIO req =ansIO req (\(StrList s)->s) succIO req = ansIO req (\Success->()) ansIO req proj = M $ \ c h -> hIOerr req h (c.proj) xrequestFIOM req = M $ \ c h -> req c