diff --git a/Data/Functor/Invariant.hs b/Data/Functor/Invariant.hs
new file mode 100644
--- /dev/null
+++ b/Data/Functor/Invariant.hs
@@ -0,0 +1,122 @@
+module Data.Functor.Invariant (Invariant(..), Invariant2(..)) where
+
+import Text.ParserCombinators.ReadP (ReadP)
+import Text.ParserCombinators.ReadPrec (ReadPrec)
+
+import qualified Control.Category as Cat
+import Control.Arrow (Arrow(..))
+import Control.Applicative (Const(Const), ZipList)
+import Control.Applicative (WrappedMonad, WrappedArrow(WrapArrow))
+
+import Control.Monad.ST (ST)
+
+import Data.Functor.Contravariant
+import Data.Functor.Contravariant.Compose
+
+
+
+
+
+-- | Any @*->*@ type parametric in the argument permits an instance of
+-- @Invariant@.
+--
+-- Instances should satisfy the following laws:
+--
+-- > invmap id id = id
+-- > invmap f2 f2' . invmap f1 f1' = invmap (f2 . f1) (f1' . f2')
+class Invariant f where
+  invmap :: (a -> b) -> (b -> a) -> f a -> f b
+
+
+
+
+
+-- | Any @*->*->*@ type parametric in both arguments permits an instance of
+-- @Invariant2@.
+--
+-- Instances should satisfy the following laws:
+--
+-- > invmap2 id id id id = id
+-- > invmap2 f2 f2' g2 g2' . invmap2 f1 f1' g1 g1' =
+-- >   invmap2 (f2 . f1) (f1' . f2') (g2 . g1) (g1' . g2')
+class Invariant2 f where
+  invmap2 :: (a -> c) -> (c -> a) -> (b -> d) -> (d -> b) -> f a b -> f c d
+
+
+
+
+
+instance Invariant Maybe where invmap = flip $ const fmap
+instance Invariant [] where invmap = flip $ const fmap
+instance Invariant IO where invmap = flip $ const fmap
+instance Invariant (ST s) where invmap = flip $ const fmap
+instance Invariant ReadP where invmap = flip $ const fmap
+instance Invariant ReadPrec where invmap = flip $ const fmap
+instance Invariant ((->) a) where invmap = flip $ const fmap
+instance Invariant (Either a) where invmap = flip $ const fmap
+instance Invariant ((,) a) where invmap = flip $ const fmap
+instance Invariant ((,,) a b) where invmap f _ ~(a, b, x) = (a, b, f x)
+instance Invariant ((,,,) a b c) where
+  invmap f _ ~(a, b, c, x) = (a, b, c, f x)
+instance Invariant ((,,,,) a b c d) where
+  invmap f _ ~(a, b, c, d, x) = (a, b, c, d, f x)
+
+instance Invariant2 (->) where invmap2 _ f' g _ = (g .) . (. f')
+instance Invariant2 Either where
+  invmap2 f _ _ _ (Left  x) = Left  $ f x
+  invmap2 _ _ g _ (Right y) = Right $ g y
+instance Invariant2 (,) where invmap2 f _ g _ ~(x, y) = (f x, g y)
+instance Invariant2 ((,,) a) where invmap2 f _ g _ ~(a, x, y) = (a, f x, g y)
+instance Invariant2 ((,,,) a b) where
+  invmap2 f _ g _ ~(a, b, x, y) = (a, b, f x, g y)
+instance Invariant2 ((,,,,) a b c) where
+  invmap2 f _ g _ ~(a, b, c, x, y) = (a, b, c, f x, g y)
+
+
+
+
+
+-- | @Control.Applicative@
+instance Invariant (Const a) where invmap _ _ (Const x) = Const x
+-- | @Control.Applicative@
+instance Invariant ZipList where invmap = flip $ const fmap
+-- | @Control.Applicative@
+instance Monad m => Invariant (WrappedMonad m) where invmap = flip $ const fmap
+-- | @Control.Applicative@
+instance Arrow arr => Invariant (WrappedArrow arr a) where
+  invmap f _ (WrapArrow x) = WrapArrow $ ((arr f) Cat.. x)
+-- | @Control.Applicative@
+instance Invariant2 Const where invmap2 f _ _ _ (Const x) = Const (f x)
+-- | @Control.Applicative@
+instance Arrow arr => Invariant2 (WrappedArrow arr) where
+  invmap2 _ f' g _ (WrapArrow x) = WrapArrow $ arr g Cat.. x Cat.. arr f'
+
+
+
+
+
+-- | from the @contravariant@ package
+instance Invariant Predicate where invmap = const contramap
+-- | from the @contravariant@ package
+instance Invariant Comparison where invmap = const contramap
+-- | from the @contravariant@ package
+instance Invariant Equivalence where invmap = const contramap
+-- | from the @contravariant@ package
+instance Invariant (Op a) where invmap = const contramap
+-- | from the @contravariant@ package
+instance Invariant2 Op where
+  invmap2 f f' g g' (Op x) = Op $ invmap2 g g' f f' x
+
+
+
+
+
+-- | from the @contravariant@ package
+instance (Invariant f, Invariant g) => Invariant (Compose f g) where
+  invmap f g (Compose x) = Compose $ invmap (invmap f g) (invmap g f) x
+-- | from the @contravariant@ package
+instance (Invariant f, Invariant g) => Invariant (ComposeCF f g) where
+  invmap f g (ComposeCF x) = ComposeCF $ invmap (invmap f g) (invmap g f) x
+-- | from the @contravariant@ package
+instance (Invariant f, Invariant g) => Invariant (ComposeFC f g) where
+  invmap f g (ComposeFC x) = ComposeFC $ invmap (invmap f g) (invmap g f) x
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,23 @@
+Copyright (c) 2012, University of Kansas
+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.
+
+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/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/invariant.cabal b/invariant.cabal
new file mode 100644
--- /dev/null
+++ b/invariant.cabal
@@ -0,0 +1,22 @@
+name: invariant
+version: 0.1.0
+synopsis: Haskell 98 invariant functors
+description: Haskell 98 invariant functors
+
+category: Control, Data
+
+license: BSD3
+license-file: LICENSE
+author: Nicolas Frisby <nicolas.frisby@gmail.com>
+maintainer: Nicolas Frisby <nicolas.frisby@gmail.com>
+
+build-type: Simple
+cabal-version: >= 1.6
+
+
+
+library
+  build-depends: base >= 4 && < 5
+  build-depends: contravariant >= 0.1.2 && < 0.3
+
+  exposed-modules: Data.Functor.Invariant
