module Control.Monad.Disj.Class (
MonadDisj(..)
) where
import Control.Monad.Trans
import qualified Control.Monad.State.Lazy as L
import qualified Control.Monad.State.Strict as S
import Control.Monad.Reader
import Control.Monad.Fresh
class Monad m => MonadDisj m where
contradictoryBecause :: Maybe String -> m a
disjunction :: m a -> m a -> m a
instance MonadDisj m => MonadDisj (L.StateT s m) where
contradictoryBecause = lift . contradictoryBecause
disjunction m1 m2 = L.StateT $ \s -> L.runStateT m1 s `disjunction` L.runStateT m2 s
instance MonadDisj m => MonadDisj (S.StateT s m) where
contradictoryBecause = lift . contradictoryBecause
disjunction m1 m2 = S.StateT $ \s -> S.runStateT m1 s `disjunction` S.runStateT m2 s
instance MonadDisj m => MonadDisj (FreshT m) where
contradictoryBecause = lift . contradictoryBecause
disjunction m1 m2 = FreshT $ unFreshT m1 `disjunction` unFreshT m2
instance MonadDisj m => MonadDisj (ReaderT r m) where
contradictoryBecause = lift . contradictoryBecause
disjunction m1 m2 = ReaderT $ \r -> runReaderT m1 r `disjunction` runReaderT m2 r