diff --git a/.gitignore b/.gitignore
new file mode 100644
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+*.hi
+*.o
+*.swp
+/dist
+
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
--- /dev/null
+++ b/.travis.yml
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,28 @@
+Copyright (c) 2015, Ross Meikleham
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+
+* Neither the name of Tainted nor the names of its
+  contributors may be used to endorse or promote products derived from
+  this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,75 @@
+# Tainted
+Tainted type, and associated operations 
+
+A Tainted type contains either a clean or dirty value. Values which are
+clean stay clean as long as an operation performed on them results
+in a clean value. If combined with a dirty value, this taints the value
+causing it to become dirty, and any further operation keeps it dirty.
+This is similar to the Maybe monad except once the dirty has been
+reached, calculations can still be performed on the value it contains.
+
+One use case is evaluating whether expressions are pure from multiple
+sources combining impure and pure values. This can be useful for
+type checking to enforce purity in certain areas. As soon as an 
+impure part of an expression is reached it taints the entire
+expression as impure.
+
+A simple example given here is a expression evaluator which is given
+values from different sources which are marked as pure or impure.
+
+```Haskell
+module TaintExample where
+
+import Data.Tainted
+
+data Expr = 
+      Number (Tainted Int)
+    | Add Expr Expr
+    
+    deriving Show
+
+pure1   = Number (Clean 3)
+pure2   = Number (Clean 7)
+impure1 = Number (Dirty 5)
+
+expr1 = Add pure1 pure2
+expr2 = Add impure1 pure1
+expr3 = Add pure1 (Add impure1 pure2) 
+
+--Evaluate expression as much as Possible
+evalExpr :: Expr -> Expr
+evalExpr (Number n) = Number n
+evalExpr (Add e1 e2) = 
+    case (evalExpr e1, evalExpr e2) of
+        (Number i, Number j) -> Number $ (+) <$> i <*> j
+        (x, y) -> Add x y
+
+reducedExpr1 = evalExpr expr1
+reducedExpr2 = evalExpr expr2
+reducedExpr3 = evalExpr expr3
+```
+
+Evaluating expr1:
+```Haskell
+Number (Clean 10)
+```
+Adding 2 clean values 7 and 3 gives a clean value, clean
+values haven't become tainted
+
+Evaluating expr2:
+```Haskell
+Number (Dirty 8)
+```
+Adding a clean value 3 and dirty value 5 taints the expression as dirty
+so the expression evaluates to dirty value of 8
+
+
+Evaluating expr3:
+```Haskell
+Number (Dirty 15)
+```
+This shows the propogation of dirty states, as the inner expression
+evaluates to a dirty value, then added with a clean value still
+gives a dirty value.
+
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/Tainted.cabal b/Tainted.cabal
new file mode 100644
--- /dev/null
+++ b/Tainted.cabal
@@ -0,0 +1,36 @@
+-- Initial Tainted.cabal generated by cabal init.  For further 
+-- documentation, see http://haskell.org/cabal/users-guide/
+
+name:                Tainted
+version:             0.0.1
+synopsis:            Tainted type, and associated operations
+description:            Tainted type, and associated operations
+homepage:            https://github.com/RossMeikleham/Tainted
+license:             BSD3
+license-file:        LICENSE
+author:              RossMeikleham
+maintainer:          rossmeikleham@hotmail.co.uk
+copyright:           Copyright (C) 2015 Ross Meikleham
+category:            Data, Monads
+build-type:          Simple
+cabal-version:       >=1.10
+extra-source-files:
+    .gitignore
+    .travis.yml
+    README.md
+
+
+source-repository head 
+    type: git
+    location: git://github.com/RossMeikleham/Tainted.git
+
+
+library
+  exposed-modules:     Data.Tainted
+  build-depends:       base >=4.8 && <4.9
+  hs-source-dirs:      src
+  default-language:    Haskell2010
+  ghc-options: -Wall
+  
+ 
+  
diff --git a/src/Data/Tainted.hs b/src/Data/Tainted.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Tainted.hs
@@ -0,0 +1,132 @@
+-----------------------------------------------------------------------------
+-- |
+-- 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 Data.Tainted 
+    (Tainted(..), isClean, isDirty, cleans, dirtys, partitionTaints)
+
+where
+
+import Control.Monad
+import Data.Typeable
+
+
+-- | The 'Tainted' type encapsulates a value.  A value of type
+-- @'Tainted' a@ either contains a "clean" value of type @a@ (represented as @'Clean' a@), 
+-- or it contains a "dirty" value of type @a@ (represented as @'Dirty' a@).  
+--
+-- The 'Tainted' type is also a monad. Once the "dirty" state has been
+-- reached, and clean operations performed themselves create a "dirty"
+-- value. 
+data Tainted a = Dirty a | Clean a
+    deriving (Eq, Ord, Read, Show, Typeable)
+
+-- Identity law:
+--
+-- fmap id (Dirty a) = Dirty (id a) = Dirty a => fmap id = id 
+-- 
+-- Same proof can be generalized for Clean
+--
+-- Composition law:
+--
+-- ((fmap p) . (fmap q)) (Dirty a) = fmap p (Dirty (q a) = (Dirty ((p . q) a)) 
+-- = fmap (p . q)
+--
+-- Same proof can be generalized for Clean
+instance Functor Tainted where
+    fmap f (Dirty a) = Dirty (f a)
+    fmap f (Clean a) = Clean (f a)
+
+
+-- Proof of correctness comes from Monad correctness
+instance Applicative Tainted where
+    pure = return
+    (<*>) = ap
+ 
+-- Left Identity Law:
+--
+-- (return x) >>= f = Clean f x  ≡ f x
+--
+-- Right Identity Law:
+--
+-- m >>= return ≡ m 
+--
+-- proof is in definition of the Clean case below for (>>=)
+--
+-- Associativity Law:
+--
+-- Case of m being Clean :
+-- 
+-- LHS: (Clean a >>= f) >>= g = f a >>= g 
+-- RHS: Clean a >>= (\x -> f x >>= g) =  f a >>= g
+-- LHS = RHS
+--
+-- Case of m being Dirty:
+--
+-- LHS: (Dirty a >>= f) >>= g = 
+--      g =<< case f a of 
+--          (Clean y) -> Dirty y
+--          y         -> y
+--
+-- RHS: Dirty a >>= (\x -> f x >>= g) = 
+--      g =<< case f a of
+--          (Clean y) -> Dirty y
+--          y         -> y    
+-- LHS = RHS
+instance Monad Tainted where
+    return = Clean
+    Dirty x  >>= f = case f x of
+                        (Clean y) -> Dirty y
+                        y -> y 
+    Clean x  >>= f = f x
+
+
+-- ---------------------------------------------------------------------------
+-- The Tainted type, and instances
+
+
+-- | Returns 'True' iff its argument is of the form 'Clean _.
+isClean :: Tainted a -> Bool
+isClean (Clean _) = True
+isClean _ = False
+
+
+-- | Returns 'True' iff its argument is of the form Dirty _.  
+isDirty :: Tainted a -> Bool 
+isDirty = not . isClean 
+
+
+-- | Extracts from a list of 'Tainted' all the 'Clean' elements. 
+--   All the 'Clean' elements are extracted in order.
+cleans :: [Tainted a] -> [a]
+cleans = map extractTaint . filter isClean 
+
+
+-- | Extracts from a list of 'Tainted' all the 'Dirty' elements.
+--   All the 'Dirty' elements are extracted in order.
+dirtys :: [Tainted a] -> [a]
+dirtys = map extractTaint . filter isDirty
+
+
+-- | Partitions a list of 'Tainted' into two lists. 
+--   All the 'Dirty' elements are extracted, in order, to the first component of the output. 
+--   Similarly the 'Clean' elements are extracted to the second component of the output.
+partitionTaints :: [Tainted a] -> ([a], [a])
+partitionTaints ts = (c, d)
+    where c = cleans  ts
+          d = dirtys  ts
+
+
+-- | Extract the value contained in a 'Tainted' type
+extractTaint :: Tainted a -> a
+extractTaint (Clean a) = a
+extractTaint (Dirty a) = a
