paragon-0.1.28: src/Language/Java/Paragon/Monad/Base.hs
module Language.Java.Paragon.Monad.Base
(
ErrCtxt, BaseM, runBaseM, runBaseErr,
MonadIO(..), MonadBase(..),
liftEither, liftShowEither, tryCatch,
getFreshInt, getErrCtxt, withErrCtxt,
check, checkM, ignore, orElse, orM, anyM,
maybeM, withFold, withFoldMap
) where
import Language.Java.Paragon.Monad.Uniq
import Control.Monad
import Control.Applicative
import System.Exit
type ErrCtxt = String -> String
newtype BaseM a = BaseM (ErrCtxt -> Uniq -> IO (Either String a))
instance Monad BaseM where
return x = BaseM $ \_ _ -> return $ Right x
BaseM f >>= k =
BaseM $ \ec u ->
do esa <- f ec u
case esa of
Left err -> return $ Left err
Right a ->
let BaseM g = k a
in g ec u
fail err = BaseM $ \ec _ -> return . Left $ ec err
runBaseM :: BaseM a -> IO (Either String a)
runBaseM (BaseM f) = do
initU <- initUniq
f id initU
runBaseErr :: BaseM a -> IO a
runBaseErr bma = do
esa <- runBaseM bma
case esa of
Left err -> do
putStrLn $ "\n\n" ++ err
exitWith $ ExitFailure (-1)
Right a -> return a
instance Functor BaseM where
fmap = liftM
getUniqRef :: MonadBase m => m Uniq
getUniqRef = liftBase $ BaseM $ \_ u -> return $ Right u
getFreshInt :: MonadBase m => m Int
getFreshInt = do
u <- getUniqRef
liftIO $ getUniq u
getErrCtxt :: MonadBase m => m ErrCtxt
getErrCtxt = liftBase $ BaseM $ \ec _ -> return $ Right ec
class Monad m => MonadIO m where
liftIO :: IO a -> m a
instance MonadIO IO where
liftIO = id
instance MonadIO BaseM where
liftIO ioa = BaseM $ \_ _ -> Right <$> ioa
class MonadIO m => MonadBase m where
liftBase :: BaseM a -> m a
withErrCtxt' :: (ErrCtxt -> ErrCtxt) -> m a -> m a
tryM :: m a -> m (Either String a)
instance MonadBase BaseM where
liftBase = id
withErrCtxt' strff (BaseM f) = BaseM $ \ec u -> f (strff ec) u
tryM (BaseM f) = BaseM $ \ec u -> do
esa <- f ec u
return $ Right esa
withErrCtxt :: MonadBase m => String -> m a -> m a
withErrCtxt str = withErrCtxt' (. (str ++))
tryCatch :: MonadBase m => m a -> (String -> m a) -> m a
tryCatch tr ctch = do esa <- tryM tr
case esa of
Right a -> return a
Left err -> ctch err
--------------------------------------------
-- --
-- Monad-independent helpers --
-- --
--------------------------------------------
liftEither :: Monad m => Either String a -> m a
liftEither esa = case esa of
Left err -> fail err
Right x -> return x
liftShowEither :: (Monad m, Show err) => Either err a -> m a
liftShowEither eerra = case eerra of
Left err -> fail $ show err
Right x -> return x
check :: Monad m => Bool -> String -> m ()
check b err = if b then return () else fail err
checkM :: Monad m => m Bool -> String -> m ()
checkM mb err = mb >>= flip check err
ignore :: Monad m => m a -> m ()
ignore = (>> return ())
orElse :: Monad m => m (Maybe a) -> m a -> m a
orElse monma mona = do
ma <- monma
case ma of
Just a -> return a
Nothing -> mona
infixr 3 `orElse`
orM :: Monad m => m Bool -> m Bool -> m Bool
orM mba mbb = do
ba <- mba
if ba then return True else mbb
anyM :: Monad m => [m Bool] -> m Bool
anyM [] = return False
anyM (m:ms) = m `orM` anyM ms
maybeM :: Monad m => Maybe a -> (a -> m ()) -> m ()
maybeM ma f = maybe (return ()) f ma
withFold :: Monad m => [m a -> m a] -> m a -> m a
withFold = foldr (.) id
withFoldMap :: Monad m => (a -> m b -> m b) -> [a] -> m b -> m b
withFoldMap f = withFold . map f