-- | Little functions connected with IO module Util.IOExtras( catchEOF, -- :: IO a -> IO (Maybe a) -- If successful return result. -- if unsuccessful because of EOF return Nothing -- otherwise pass on error catchAlreadyExists, -- :: IO a -> IO (Maybe a) -- If successful return results, -- If unsuccessful because of an isAlreadyExists error return Nothing -- otherwise pass on error. catchDoesNotExist, -- :: IO a -> IO (Maybe a) catchErrorCalls, -- :: IO a -> IO (Either String a) -- Catch all calls to the error function. hGetLineR, -- :: Read a => Handle -> IO a -- hGetLine and then read. simpleModifyIORef, -- :: IORef a -> (a -> (a,b)) -> IO b -- carry out a pure modification of an IORef. ) where import System.IO.Error import System.IO import Data.IORef import Control.Exception catchEOF :: IO a -> IO (Maybe a) catchEOF action = catchGeneral isEOFError action catchAlreadyExists :: IO a -> IO (Maybe a) catchAlreadyExists action = catchGeneral isAlreadyExistsError action catchDoesNotExist :: IO a -> IO (Maybe a) catchDoesNotExist action = catchGeneral isDoesNotExistError action catchGeneral :: (IOError -> Bool) -> IO a -> IO (Maybe a) catchGeneral discriminator action = do result <- tryJust (\ ioErr -> if discriminator ioErr then Just () else Nothing ) action case result of Left () -> return Nothing Right success -> return (Just success) catchErrorCalls :: IO a -> IO (Either ErrorCall a) catchErrorCalls = Control.Exception.try hGetLineR :: Read a => Handle -> IO a hGetLineR handle = do line <- hGetLine handle return (read line) simpleModifyIORef :: IORef a -> (a -> (a,b)) -> IO b simpleModifyIORef = atomicModifyIORef