----------------------------------------------------------------------------- -- | -- Module : Control.Monad -- Copyright : Ross Meikleham -- License : BSD-style -- -- Maintainer : RossMeikleham@hotmail.co.uk -- Stability : provisional -- Portability : portable -- -- The Tainted type, and associated operations. ----------------------------------------------------------------------------- module Control.Monad.Trans.Tainted(TaintedT(..), hoistTainted) where import Control.Monad import Control.Monad.Trans import Control.Applicative import Data.Tainted -- | 'TaintedT' is a monad transformed of 'Tainted' newtype TaintedT m a = TaintedT {runTainted :: m (Tainted a)} instance (Monad m, Functor m) => Functor (TaintedT m) where fmap f = TaintedT . fmap (fmap f) . runTainted instance (Monad m, Functor m) => Applicative (TaintedT m) where pure = return (<*>) = ap instance Monad m => Monad (TaintedT m) where return = TaintedT . return . return TaintedT x >>= f = TaintedT $ do res <- x case res of Clean v -> runTainted $ f v Dirty t -> do -- Ensure Dirty stays Dirty res <- runTainted $ f t return $ case res of Clean u -> Dirty u d -> d instance MonadTrans TaintedT where lift = TaintedT . liftM return -- | Lift a 'Tainted' into an 'TaintedT' hoistTainted :: Monad m => Tainted a -> TaintedT m a hoistTainted = TaintedT . return