Use MonadThrow/MonadCatch for MonadConc exceptions

This commit is contained in:
Michael Walker 2015-02-12 13:31:48 +00:00
parent ef580d66e8
commit 5ce63d0d50
3 changed files with 34 additions and 1 deletions

View File

@ -7,7 +7,9 @@ module Control.Monad.Conc.Class where
import Control.Concurrent (forkIO) import Control.Concurrent (forkIO)
import Control.Concurrent.MVar (MVar, readMVar, newEmptyMVar, putMVar, tryPutMVar, takeMVar, tryTakeMVar) import Control.Concurrent.MVar (MVar, readMVar, newEmptyMVar, putMVar, tryPutMVar, takeMVar, tryTakeMVar)
import Control.Exception (Exception)
import Control.Monad (unless, void) import Control.Monad (unless, void)
import Control.Monad.Catch (MonadCatch, MonadThrow, catch, throwM)
import Control.Monad.STM (STM) import Control.Monad.STM (STM)
import Control.Monad.STM.Class (MonadSTM) import Control.Monad.STM.Class (MonadSTM)
@ -36,7 +38,7 @@ import qualified Control.Monad.STM as S
-- 'takeCVar' and 'putCVar', however, are very inefficient, and should -- 'takeCVar' and 'putCVar', however, are very inefficient, and should
-- probably always be overridden to make use of -- probably always be overridden to make use of
-- implementation-specific blocking functionality. -- implementation-specific blocking functionality.
class (Monad m, MonadSTM (STMLike m)) => MonadConc m where class (Monad m, MonadCatch m, MonadSTM (STMLike m), MonadThrow m) => MonadConc m where
-- | The associated 'MonadSTM' for this class. -- | The associated 'MonadSTM' for this class.
type STMLike m :: * -> * type STMLike m :: * -> *
@ -100,6 +102,21 @@ class (Monad m, MonadSTM (STMLike m)) => MonadConc m where
-- | Perform a series of STM actions atomically. -- | Perform a series of STM actions atomically.
atomically :: STMLike m a -> m a atomically :: STMLike m a -> m a
-- | Throw an exception. This will \"bubble up\" looking for an
-- exception handler capable of dealing with it and, if one is not
-- found, the thread is killed.
--
-- > throw = throwM
throw :: Exception e => e -> m a
throw = throwM
-- | Catch an exception. This is only required to be able to catch
-- exceptions raised by 'throw', unlike the more general
-- Control.Exception.catch function. If you need to be able to catch
-- /all/ errors, you will have to use 'IO'.
catch :: Exception e => m a -> (e -> m a) -> m a
catch = Control.Monad.Catch.catch
-- | Runs its argument, just as if the @_concNoTest@ weren't there. -- | Runs its argument, just as if the @_concNoTest@ weren't there.
-- --
-- > _concNoTest x = x -- > _concNoTest x = x

View File

@ -41,6 +41,8 @@ module Test.DejaFu.Deterministic
) where ) where
import Control.Applicative (Applicative(..), (<$>)) import Control.Applicative (Applicative(..), (<$>))
import Control.Exception (Exception)
import Control.Monad.Catch (MonadCatch(..), MonadThrow(..))
import Control.Monad.Cont (cont, runCont) import Control.Monad.Cont (cont, runCont)
import Control.Monad.ST (ST, runST) import Control.Monad.ST (ST, runST)
import Control.State (Wrapper(..), refST) import Control.State (Wrapper(..), refST)
@ -57,6 +59,12 @@ import qualified Control.Monad.Conc.Class as C
-- monad. -- monad.
newtype Conc t a = C { unC :: M (ST t) (STRef t) (STMLike t) a } deriving (Functor, Applicative, Monad) newtype Conc t a = C { unC :: M (ST t) (STRef t) (STMLike t) a } deriving (Functor, Applicative, Monad)
instance MonadCatch (Conc t) where
catch = error "Exceptions not yet handled in Conc."
instance MonadThrow (Conc t) where
throwM = error "Exceptions not yet handled in Conc."
instance C.MonadConc (Conc t) where instance C.MonadConc (Conc t) where
type CVar (Conc t) = CVar t type CVar (Conc t) = CVar t
type STMLike (Conc t) = STMLike t (ST t) (STRef t) type STMLike (Conc t) = STMLike t (ST t) (STRef t)

View File

@ -45,6 +45,8 @@ module Test.DejaFu.Deterministic.IO
) where ) where
import Control.Applicative (Applicative(..), (<$>)) import Control.Applicative (Applicative(..), (<$>))
import Control.Exception (Exception)
import Control.Monad.Catch (MonadCatch(..), MonadThrow(..))
import Control.Monad.Cont (cont, runCont) import Control.Monad.Cont (cont, runCont)
import Control.State (Wrapper(..), refIO) import Control.State (Wrapper(..), refIO)
import Data.IORef (IORef, newIORef) import Data.IORef (IORef, newIORef)
@ -58,6 +60,12 @@ import qualified Control.Monad.IO.Class as IO
-- | The 'IO' variant of Test.DejaFu.Deterministic's @Conc@ monad. -- | The 'IO' variant of Test.DejaFu.Deterministic's @Conc@ monad.
newtype ConcIO t a = C { unC :: M IO IORef (STMLike t) a } deriving (Functor, Applicative, Monad) newtype ConcIO t a = C { unC :: M IO IORef (STMLike t) a } deriving (Functor, Applicative, Monad)
instance MonadCatch (ConcIO t) where
catch = error "Exceptions not yet handled in ConcIO."
instance MonadThrow (ConcIO t) where
throwM = error "Exceptions not yet handled in ConcIO."
instance IO.MonadIO (ConcIO t) where instance IO.MonadIO (ConcIO t) where
liftIO = liftIO liftIO = liftIO