module FudgetIOMonad where import Prelude hiding (readFile,writeFile, putStr,putStrLn,getLine,readLn,print, catch,ioError) import AllFudgets import AbstractIO import DialogueIO as D import MUtils import MT (MT(..)) newtype FIOM f i o a = M {unM::(a->f i o)->(D.IOError->f i o)->f i o} runFIOM (M m) = m (const end) (error.show) instance Functor (FIOM f i o) where fmap f (M m) = M $ \ c h -> m (c.f) h instance Monad (FIOM f i o) 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 ()) {- -- This causes weird type checking problems with GHC. Overlapping instances? class Monad m => SPIO m i o | m -> i o where putM :: o -> m () getM :: m i instance StreamProcIO f => SPIO (FIOM f i o) i o where putM = putFM getM = getFM instance (Monad (t m),MT t,SPIO m i o) => SPIO (t m) i o where putM = lift . putM getM = lift getM -} -------------------------------------------------------------------------------- instance FudgetIO f => FileIO (FIOM f i o) where readFile = strIO . ReadFile writeFile path s = succIO (WriteFile path s) instance CatchIO D.IOError (FIOM f i o) where M m `catch` h = M $ \ c h' -> m c (\e->unM (h e) c h') ioError e = M $ \ _ h -> h e instance FudgetIO f => DirectoryIO (FIOM f i o) where createDirectory path = succIO (CreateDirectory path "") removeFile = succIO . DeleteFile getDirectoryContents = strListIO . ReadDirectory doesDirectoryExist path = (((==)"d").take 1) # statusFile path statusFile = strIO . StatusFile instance FudgetIO f => SystemIO (FIOM f i o) where system cmd = succIO (System cmd) >> return ExitSuccess -- !! instance IOErr D.IOError where isDoesNotExistError (ReadError _) = True isDoesNotExistError _ = 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)