{-# LANGUAGE DeriveDataTypeable #-}
module Data.Tainted
(Tainted(..), isClean, isDirty, cleans, dirtys, partitionTaints)
where
import Control.Monad
import Control.Applicative
import Data.Typeable
data Tainted a = Dirty a | Clean a
deriving (Tainted a -> Tainted a -> Bool
(Tainted a -> Tainted a -> Bool)
-> (Tainted a -> Tainted a -> Bool) -> Eq (Tainted a)
forall a. Eq a => Tainted a -> Tainted a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Tainted a -> Tainted a -> Bool
== :: Tainted a -> Tainted a -> Bool
$c/= :: forall a. Eq a => Tainted a -> Tainted a -> Bool
/= :: Tainted a -> Tainted a -> Bool
Eq, Eq (Tainted a)
Eq (Tainted a) =>
(Tainted a -> Tainted a -> Ordering)
-> (Tainted a -> Tainted a -> Bool)
-> (Tainted a -> Tainted a -> Bool)
-> (Tainted a -> Tainted a -> Bool)
-> (Tainted a -> Tainted a -> Bool)
-> (Tainted a -> Tainted a -> Tainted a)
-> (Tainted a -> Tainted a -> Tainted a)
-> Ord (Tainted a)
Tainted a -> Tainted a -> Bool
Tainted a -> Tainted a -> Ordering
Tainted a -> Tainted a -> Tainted a
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (Tainted a)
forall a. Ord a => Tainted a -> Tainted a -> Bool
forall a. Ord a => Tainted a -> Tainted a -> Ordering
forall a. Ord a => Tainted a -> Tainted a -> Tainted a
$ccompare :: forall a. Ord a => Tainted a -> Tainted a -> Ordering
compare :: Tainted a -> Tainted a -> Ordering
$c< :: forall a. Ord a => Tainted a -> Tainted a -> Bool
< :: Tainted a -> Tainted a -> Bool
$c<= :: forall a. Ord a => Tainted a -> Tainted a -> Bool
<= :: Tainted a -> Tainted a -> Bool
$c> :: forall a. Ord a => Tainted a -> Tainted a -> Bool
> :: Tainted a -> Tainted a -> Bool
$c>= :: forall a. Ord a => Tainted a -> Tainted a -> Bool
>= :: Tainted a -> Tainted a -> Bool
$cmax :: forall a. Ord a => Tainted a -> Tainted a -> Tainted a
max :: Tainted a -> Tainted a -> Tainted a
$cmin :: forall a. Ord a => Tainted a -> Tainted a -> Tainted a
min :: Tainted a -> Tainted a -> Tainted a
Ord, ReadPrec [Tainted a]
ReadPrec (Tainted a)
Int -> ReadS (Tainted a)
ReadS [Tainted a]
(Int -> ReadS (Tainted a))
-> ReadS [Tainted a]
-> ReadPrec (Tainted a)
-> ReadPrec [Tainted a]
-> Read (Tainted a)
forall a. Read a => ReadPrec [Tainted a]
forall a. Read a => ReadPrec (Tainted a)
forall a. Read a => Int -> ReadS (Tainted a)
forall a. Read a => ReadS [Tainted a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: forall a. Read a => Int -> ReadS (Tainted a)
readsPrec :: Int -> ReadS (Tainted a)
$creadList :: forall a. Read a => ReadS [Tainted a]
readList :: ReadS [Tainted a]
$creadPrec :: forall a. Read a => ReadPrec (Tainted a)
readPrec :: ReadPrec (Tainted a)
$creadListPrec :: forall a. Read a => ReadPrec [Tainted a]
readListPrec :: ReadPrec [Tainted a]
Read, Int -> Tainted a -> ShowS
[Tainted a] -> ShowS
Tainted a -> String
(Int -> Tainted a -> ShowS)
-> (Tainted a -> String)
-> ([Tainted a] -> ShowS)
-> Show (Tainted a)
forall a. Show a => Int -> Tainted a -> ShowS
forall a. Show a => [Tainted a] -> ShowS
forall a. Show a => Tainted a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Tainted a -> ShowS
showsPrec :: Int -> Tainted a -> ShowS
$cshow :: forall a. Show a => Tainted a -> String
show :: Tainted a -> String
$cshowList :: forall a. Show a => [Tainted a] -> ShowS
showList :: [Tainted a] -> ShowS
Show, Typeable)
instance Functor Tainted where
fmap :: forall a b. (a -> b) -> Tainted a -> Tainted b
fmap a -> b
f (Dirty a
a) = b -> Tainted b
forall a. a -> Tainted a
Dirty (a -> b
f a
a)
fmap a -> b
f (Clean a
a) = b -> Tainted b
forall a. a -> Tainted a
Clean (a -> b
f a
a)
instance Applicative Tainted where
pure :: forall a. a -> Tainted a
pure = a -> Tainted a
forall a. a -> Tainted a
forall (m :: * -> *) a. Monad m => a -> m a
return
<*> :: forall a b. Tainted (a -> b) -> Tainted a -> Tainted b
(<*>) = Tainted (a -> b) -> Tainted a -> Tainted b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
instance Monad Tainted where
return :: forall a. a -> Tainted a
return = a -> Tainted a
forall a. a -> Tainted a
Clean
Dirty a
x >>= :: forall a b. Tainted a -> (a -> Tainted b) -> Tainted b
>>= a -> Tainted b
f = case a -> Tainted b
f a
x of
(Clean b
y) -> b -> Tainted b
forall a. a -> Tainted a
Dirty b
y
Tainted b
y -> Tainted b
y
Clean a
x >>= a -> Tainted b
f = a -> Tainted b
f a
x
isClean :: Tainted a -> Bool
isClean :: forall a. Tainted a -> Bool
isClean (Clean a
_) = Bool
True
isClean Tainted a
_ = Bool
False
isDirty :: Tainted a -> Bool
isDirty :: forall a. Tainted a -> Bool
isDirty = Bool -> Bool
not (Bool -> Bool) -> (Tainted a -> Bool) -> Tainted a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tainted a -> Bool
forall a. Tainted a -> Bool
isClean
cleans :: [Tainted a] -> [a]
cleans :: forall a. [Tainted a] -> [a]
cleans = (Tainted a -> a) -> [Tainted a] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map Tainted a -> a
forall a. Tainted a -> a
extractTaint ([Tainted a] -> [a])
-> ([Tainted a] -> [Tainted a]) -> [Tainted a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tainted a -> Bool) -> [Tainted a] -> [Tainted a]
forall a. (a -> Bool) -> [a] -> [a]
filter Tainted a -> Bool
forall a. Tainted a -> Bool
isClean
dirtys :: [Tainted a] -> [a]
dirtys :: forall a. [Tainted a] -> [a]
dirtys = (Tainted a -> a) -> [Tainted a] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map Tainted a -> a
forall a. Tainted a -> a
extractTaint ([Tainted a] -> [a])
-> ([Tainted a] -> [Tainted a]) -> [Tainted a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tainted a -> Bool) -> [Tainted a] -> [Tainted a]
forall a. (a -> Bool) -> [a] -> [a]
filter Tainted a -> Bool
forall a. Tainted a -> Bool
isDirty
partitionTaints :: [Tainted a] -> ([a], [a])
partitionTaints :: forall a. [Tainted a] -> ([a], [a])
partitionTaints [Tainted a]
ts = ([a]
c, [a]
d)
where c :: [a]
c = [Tainted a] -> [a]
forall a. [Tainted a] -> [a]
cleans [Tainted a]
ts
d :: [a]
d = [Tainted a] -> [a]
forall a. [Tainted a] -> [a]
dirtys [Tainted a]
ts
extractTaint :: Tainted a -> a
(Clean a
a) = a
a
extractTaint (Dirty a
a) = a
a