type IOE a = IO a

IOE used to be a monad with extra error handling built on top of the IO monad,
But the IO monad already supports error handling, so this construction was a
superfluous.

The new 'instance ErrorMonad IOE' is defined to preserve the previous error
handling behaviour, i.e. the function 'handle' only catches errors thrown with
'raise' (or 'fail') and not other errors in the IO monad.
This commit is contained in:
hallgren
2014-10-20 19:32:46 +00:00
parent 55aebadd5a
commit 8337a19b40
2 changed files with 23 additions and 15 deletions

View File

@@ -79,7 +79,7 @@ batchCompile1 lib_dir (opts,filepaths) =
deps <- newMVar M.empty deps <- newMVar M.empty
toLog <- newLog runIOE toLog <- newLog runIOE
let --logStrLn = toLog . ePutStrLn let --logStrLn = toLog . ePutStrLn
ok :: CollectOutput IOE a -> IO a --ok :: CollectOutput IO a -> IO a
ok (CO m) = err bad good =<< appIOE m ok (CO m) = err bad good =<< appIOE m
where where
good (o,r) = do toLog o; return r good (o,r) = do toLog o; return r

View File

@@ -32,7 +32,7 @@ import System.Exit
import System.CPUTime import System.CPUTime
--import System.Cmd --import System.Cmd
import Text.Printf import Text.Printf
import Control.Applicative(Applicative(..)) --import Control.Applicative(Applicative(..))
import Control.Monad import Control.Monad
import Control.Monad.Trans(MonadIO(..)) import Control.Monad.Trans(MonadIO(..))
import Control.Exception(evaluate) import Control.Exception(evaluate)
@@ -125,19 +125,27 @@ splitInModuleSearchPath s = case break isPathSep s of
-- ** IO monad with error; adapted from state monad -- ** IO monad with error; adapted from state monad
newtype IOE a = IOE { appIOE :: IO (Err a) } -- | Was: @newtype IOE a = IOE { appIOE :: IO (Err a) }@
type IOE a = IO a
ioe :: IO (Err a) -> IOE a ioe :: IO (Err a) -> IOE a
ioe = IOE ioe io = err fail return =<< io
runIOE m = err fail return =<< appIOE m appIOE :: IOE a -> IO (Err a)
appIOE ioe = handle (fmap Ok ioe) (return . Bad)
instance MonadIO IOE where liftIO io = ioe (io >>= return . return) runIOE :: IOE a -> IO a
runIOE = id
instance ErrorMonad IOE where -- instance MonadIO IOE where liftIO io = ioe (io >>= return . return)
raise = ioe . return . Bad
handle m h = ioe $ err (appIOE . h) (return . Ok) =<< appIOE m
-- | Make raise and handle mimic behaviour of the old IOE monad
instance ErrorMonad IO where
raise = fail
handle m h = catch m $ \ e -> if isUserError e
then h (ioeGetErrorString e)
else ioError e
{-
instance Functor IOE where fmap = liftM instance Functor IOE where fmap = liftM
instance Applicative IOE where instance Applicative IOE where
@@ -150,12 +158,12 @@ instance Monad IOE where
x <- c -- Err a x <- c -- Err a
appIOE $ err raise f x -- f :: a -> IOE a appIOE $ err raise f x -- f :: a -> IOE a
fail = raise fail = raise
-}
useIOE :: a -> IOE a -> IO a useIOE :: a -> IOE a -> IO a
useIOE a ioe = appIOE ioe >>= err (\s -> putStrLn s >> return a) return useIOE a ioe = handle ioe (\s -> putStrLn s >> return a)
maybeIO io = either (const Nothing) Just `fmap` liftIO (try io) maybeIO io = either (const Nothing) Just `fmap` liftIO (try io)
{-
--foldIOE :: (a -> b -> IOE a) -> a -> [b] -> IOE (a, Maybe String) --foldIOE :: (a -> b -> IOE a) -> a -> [b] -> IOE (a, Maybe String)
foldIOE f s xs = case xs of foldIOE f s xs = case xs of
[] -> return (s,Nothing) [] -> return (s,Nothing)
@@ -164,7 +172,7 @@ foldIOE f s xs = case xs of
case ev of case ev of
Ok v -> foldIOE f v xx Ok v -> foldIOE f v xx
Bad m -> return $ (s, Just m) Bad m -> return $ (s, Just m)
-}
die :: String -> IO a die :: String -> IO a
die s = do hPutStrLn stderr s die s = do hPutStrLn stderr s
exitFailure exitFailure
@@ -181,13 +189,13 @@ instance Output IO where
where oops _ = ePutStrLn "" -- prevent crash on character encoding problem where oops _ = ePutStrLn "" -- prevent crash on character encoding problem
putStrLnE s = putStrLn s >> hFlush stdout putStrLnE s = putStrLn s >> hFlush stdout
putStrE s = putStr s >> hFlush stdout putStrE s = putStr s >> hFlush stdout
{-
instance Output IOE where instance Output IOE where
ePutStr = liftIO . ePutStr ePutStr = liftIO . ePutStr
ePutStrLn = liftIO . ePutStrLn ePutStrLn = liftIO . ePutStrLn
putStrLnE = liftIO . putStrLnE putStrLnE = liftIO . putStrLnE
putStrE = liftIO . putStrE putStrE = liftIO . putStrE
-}
--putPointE :: Verbosity -> Options -> String -> IO a -> IO a --putPointE :: Verbosity -> Options -> String -> IO a -> IO a
putPointE v opts msg act = do putPointE v opts msg act = do
when (verbAtLeast opts v) $ putStrE msg when (verbAtLeast opts v) $ putStrE msg