module Control.Monad.Trans.Tainted(TaintedT(..), hoistTainted)
where
import Control.Monad
import Control.Monad.Trans
import Control.Applicative
import Data.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
res <- runTainted $ f t
return $ case res of
Clean u -> Dirty u
d -> d
instance MonadTrans TaintedT where
lift = TaintedT . liftM return
hoistTainted :: Monad m => Tainted a -> TaintedT m a
hoistTainted = TaintedT . return