# LANGUAGE GeneralizedNewtypeDeriving , DeriveDataTypeable #
-- |
  Copyright    : ( c ) 2011  
-- License     : GPL v3 (see LICENSE)
-- 
  Maintainer   :   <  >
-- Portability : unknown
--
-- A monad to represent logical disjunctions.
module Control.Monad.Disj.Class (
  -- * The @MonadDisj@ 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


------------------------------------------------------------------------------
  The MonadDisj class
------------------------------------------------------------------------------


class Monad m => MonadDisj m where
    -- | Mark a contradiction.
    contradictoryBecause :: Maybe String -> m a
  |  two computations .
    disjunction          :: m a -> m a -> m a


------------------------------------------------------------------------------
-- Instances
------------------------------------------------------------------------------

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




 |
 License     : GPL v3 (see LICENSE)
 
 Portability : unknown

 A monad to represent logical disjunctions.
 * The @MonadDisj@ class
----------------------------------------------------------------------------
----------------------------------------------------------------------------
 | Mark a contradiction.
----------------------------------------------------------------------------
 Instances
----------------------------------------------------------------------------
# LANGUAGE GeneralizedNewtypeDeriving , DeriveDataTypeable #
  Copyright    : ( c ) 2011  
  Maintainer   :   <  >
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


  The MonadDisj class


class Monad m => MonadDisj m where
    contradictoryBecause :: Maybe String -> m a
  |  two computations .
    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



