diff --git a/Control/Monad/Morph.hs b/Control/Monad/Morph.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Morph.hs
@@ -0,0 +1,424 @@
+{-| A monad morphism is a natural transformation:
+
+> morph :: forall a . m a -> n a
+
+    ... that obeys the following two laws:
+
+> morph $ do x <- m  =  do x <- morph m
+>            f x           morph (f x)
+> 
+> morph (return x) = return x
+
+    ... which are equivalent to the following two functor laws:
+
+> morph . (f >=> g) = morph . f >=> morph . g
+> 
+> morph . return = return
+
+    Examples of monad morphisms include:
+
+    * 'lift' (from 'MonadTrans')
+
+    * 'squash' (See below)
+
+    * @'hoist' f@ (See below), if @f@ is a monad morphism
+
+    * @(f . g)@, if @f@ and @g@ are both monad morphisms
+
+    * 'id'
+
+    Monad morphisms commonly arise when manipulating existing monad transformer
+    code for compatibility purposes.  The 'MFunctor', 'MonadTrans', and
+    'MMonad' classes define standard ways to change monad transformer stacks:
+
+    * 'lift' introduces a new monad transformer layer of any type.
+
+    * 'squash' flattens two identical monad transformer layers into a single
+      layer of the same type.
+
+    * 'hoist' maps monad morphisms to modify deeper layers of the monad
+       transformer stack.
+
+-}
+
+{-# LANGUAGE Rank2Types #-}
+
+module Control.Monad.Morph (
+    -- * Functors over Monads
+    MFunctor(..),
+    -- * Monads over Monads
+    MMonad(..),
+    MonadTrans(lift),
+    squash,
+    (>|>),
+    (<|<),
+    (=<|),
+    (|>=)
+
+    -- * Tutorial
+    -- $tutorial
+
+    -- ** Generalizing base monads
+    -- $generalize
+
+    -- ** Monad morphisms
+    -- $mmorph
+
+    -- ** Mixing diverse transformers
+    -- $interleave
+
+    -- ** Embedding transformers
+    -- $embed
+    ) where
+
+import Control.Monad.Trans.Class (MonadTrans(lift))
+import qualified Control.Monad.Trans.Error         as E
+import qualified Control.Monad.Trans.Identity      as I
+import qualified Control.Monad.Trans.Maybe         as M
+import qualified Control.Monad.Trans.Reader        as R
+import qualified Control.Monad.Trans.RWS.Lazy      as RWS
+import qualified Control.Monad.Trans.RWS.Strict    as RWS'
+import qualified Control.Monad.Trans.State.Lazy    as S 
+import qualified Control.Monad.Trans.State.Strict  as S'
+import qualified Control.Monad.Trans.Writer.Lazy   as W'
+import qualified Control.Monad.Trans.Writer.Strict as W
+import Data.Monoid (Monoid, mappend)
+
+-- For documentation
+import Control.Exception (try, IOException)
+import Control.Monad ((=<<), (>=>), (<=<), join)
+import Data.Functor.Identity (Identity)
+
+{-| A functor in the category of monads, using 'hoist' as the analog of 'fmap':
+
+> hoist (f . g) = hoist f . hoist g
+> 
+> hoist id = id
+-}
+class MFunctor t where
+    {-| Lift a monad morphism from @m@ to @n@ into a monad morphism from
+        @(t m)@ to @(t n)@
+    -}
+    hoist :: (Monad m) => (forall a . m a -> n a) -> t m b -> t n b
+
+instance MFunctor (E.ErrorT e) where
+    hoist nat m = E.ErrorT (nat (E.runErrorT m))
+
+instance MFunctor I.IdentityT where
+    hoist nat m = I.IdentityT (nat (I.runIdentityT m))
+
+instance MFunctor M.MaybeT where
+    hoist nat m = M.MaybeT (nat (M.runMaybeT m))
+
+instance MFunctor (R.ReaderT r) where
+    hoist nat m = R.ReaderT (\i -> nat (R.runReaderT m i))
+
+instance MFunctor (RWS.RWST r w s) where
+    hoist nat m = RWS.RWST (\r s -> nat (RWS.runRWST m r s))
+
+instance MFunctor (RWS'.RWST r w s) where
+    hoist nat m = RWS'.RWST (\r s -> nat (RWS'.runRWST m r s))
+
+instance MFunctor (S.StateT s) where
+    hoist nat m = S.StateT (\s -> nat (S.runStateT m s))
+
+instance MFunctor (S'.StateT s) where
+    hoist nat m = S'.StateT (\s -> nat (S'.runStateT m s))
+
+instance MFunctor (W.WriterT w) where
+    hoist nat m = W.WriterT (nat (W.runWriterT m))
+
+instance MFunctor (W'.WriterT w) where
+    hoist nat m = W'.WriterT (nat (W'.runWriterT m))
+
+{-| A monad in the category of monads, using 'lift' from 'MonadTrans' as the
+    analog of 'return' and 'embed' as the analog of ('=<<'):
+
+> embed lift = id
+> 
+> embed f (lift m) = f m
+> 
+> embed g (embed f t) = embed (\m -> embed g (f m)) t
+-}
+class (MFunctor t, MonadTrans t) => MMonad t where
+    {-| Embed a newly created 'MMonad' layer within an existing layer
+
+        'embed' is analogous to ('=<<')
+    -}
+    embed :: (Monad n) => (forall a . m a -> t n a) -> t m b -> t n b
+
+{-| Squash two 'MMonad' layers into a single layer
+
+    'squash' is analogous to 'join'
+-}
+squash :: (Monad m, MMonad t) => t (t m) a -> t m a
+squash = embed id
+{-# INLINABLE squash #-}
+
+infixr 2 >|>, =<|
+infixl 2 <|<, |>=
+
+{-| Compose two 'MMonad' layer-building functions
+
+    ('>|>') is analogous to ('>=>')
+-}
+(>|>)
+    :: (Monad m3, MMonad t)
+    => (forall a . m1 a -> t m2 a)
+    -> (forall b . m2 b -> t m3 b)
+    ->             m1 c -> t m3 c
+(f >|> g) m = embed g (f m)
+{-# INLINABLE (>|>) #-}
+
+{-| Equivalent to ('>|>') with the arguments flipped
+
+    ('<|<') is analogous to ('<=<')
+-}
+(<|<)
+    :: (Monad m3, MMonad t)
+    => (forall b . m2 b -> t m3 b)
+    -> (forall a . m1 a -> t m2 a)
+    ->             m1 c -> t m3 c
+(g <|< f) m = embed g (f m)
+{-# INLINABLE (<|<) #-}
+
+{-| An infix operator equivalent to 'embed'
+
+    ('=<|') is analogous to ('=<<')
+-}
+(=<|) :: (Monad n, MMonad t) => (forall a . m a -> t n a) -> t m b -> t n b
+(=<|) = embed
+{-# INLINABLE (=<|) #-}
+
+{-| Equivalent to ('=<|') with the arguments flipped
+
+    ('|>=') is analogous to ('>>=')
+-}
+(|>=) :: (Monad n, MMonad t) => t m b -> (forall a . m a -> t n a) -> t n b
+t |>= f = embed f t
+{-# INLINABLE (|>=) #-}
+
+instance (E.Error e) => MMonad (E.ErrorT e) where
+    embed f m = E.ErrorT (do 
+        x <- E.runErrorT (f (E.runErrorT m))
+        return (case x of
+            Left         e  -> Left e
+            Right (Left  e) -> Left e
+            Right (Right a) -> Right a ) )
+
+instance MMonad I.IdentityT where
+    embed f m = f (I.runIdentityT m)
+
+instance MMonad M.MaybeT where
+    embed f m = M.MaybeT (do
+        x <- M.runMaybeT (f (M.runMaybeT m))
+        return (case x of
+            Nothing       -> Nothing
+            Just Nothing  -> Nothing
+            Just (Just a) -> Just a ) )
+
+instance MMonad (R.ReaderT r) where
+    embed f m = R.ReaderT (\i -> R.runReaderT (f (R.runReaderT m i)) i)
+
+instance (Monoid w) => MMonad (W.WriterT w) where
+    embed f m = W.WriterT (do
+        ~((a, w1), w2) <- W.runWriterT (f (W.runWriterT m))
+        return (a, mappend w1 w2) )
+
+instance (Monoid w) => MMonad (W'.WriterT w) where
+    embed f m = W'.WriterT (do
+        ((a, w1), w2) <- W'.runWriterT (f (W'.runWriterT m))
+        return (a, mappend w1 w2) )
+
+{- $tutorial
+    Monad morphisms solve the common problem of fixing monadic code after the
+    fact without modifying the original source code or type signatures.  The
+    following sections illustrate various examples of transparently modifying
+    existing functions.
+-}
+
+{- $generalize
+    Imagine that some library provided the following 'S.State' code:
+
+> import Control.Monad.Trans.State
+> 
+> tick :: State Int ()
+> tick = modify (+1)
+
+    ... but we would prefer to reuse @tick@ within a larger
+    @('S.StateT' Int 'IO')@ block in order to mix in 'IO' actions.
+
+    We could patch the original library to generalize @tick@'s type signature:
+
+> tick :: (Monad m) => StateT Int m ()
+
+    ... but we would prefer not to fork upstream code if possible.  How could
+    we generalize @tick@'s type without modifying the original code?
+
+    We can solve this if we realize that 'S.State' is a type synonym for
+    'S.StateT' with an 'Identity' base monad:
+
+> type State s = StateT s Identity
+
+    ... which means that @tick@'s true type is actually:
+
+> tick :: StateT Int Identity ()
+
+    Now all we need is a function that @generalize@s the 'Identity' base monad
+    to be any monad:
+
+> import Data.Functor.Identity
+> 
+> generalize :: (Monad m) => Identity a -> m a
+> generalize m = return (runIdentity m)
+
+    ... which we can 'hoist' to change @tick@'s base monad:
+
+> hoist :: (Monad m, MFunctor t) => (forall a . m a -> n a) -> t m b -> t n b
+> 
+> hoist generalize :: (Monad m, MFunctor t) => t Identity b -> t m b
+> 
+> hoist generalize tick :: (Monad m) => StateT Int m ()
+
+    This lets us mix @tick@ alongside 'IO' using 'lift':
+
+> import Control.Monad.Morph
+> import Control.Monad.Trans.Class
+> 
+> tock                        ::                   StateT Int IO ()
+> tock = do
+>     hoist generalize tick   :: (Monad      m) => StateT Int m  ()
+>     lift $ putStrLn "Tock!" :: (MonadTrans t) => t          IO ()
+
+>>> runStateT tock 0
+Tock!
+((), 1)
+
+-}
+
+{- $mmorph
+    Notice that @generalize@ is a monad morphism, and the following two proofs
+    show how @generalize@ satisfies the monad morphism laws.  You can refer to
+    these proofs as an example for how to prove a function obeys the monad
+    morphism laws:
+
+> generalize (return x)
+> 
+> -- Definition of 'return' for the Identity monad
+> = generalize (Identity x)
+> 
+> -- Definition of 'generalize'
+> = return (runIdentity (Identity x))
+> 
+> -- runIdentity (Identity x) = x
+> = return x
+
+> generalize $ do x <- m
+>                 f x
+> 
+> -- Definition of (>>=) for the Identity monad
+> = generalize (f (runIdentity m))
+> 
+> -- Definition of 'generalize'
+> = return (runIdentity (f (runIdentity m)))
+> 
+> -- Monad law: Left identity
+> = do x <- return (runIdentity m)
+>      return (runIdentity (f x))
+> 
+> -- Definition of 'generalize' in reverse
+> = do x <- generalize m
+>      generalize (f x)
+-}
+
+{- $interleave
+    You can combine 'hoist' and 'lift' to insert arbitrary layers anywhere
+    within a monad transformer stack.  This comes in handy when interleaving two
+    diverse stacks.
+
+    For example, we might want to combine the following @save@ function:
+
+> import Control.Monad.Trans.Writer
+> 
+> -- i.e. :: StateT Int (WriterT [Int] Identity) ()
+> save    :: StateT Int (Writer  [Int]) ()
+> save = do
+>     n <- get
+>     lift $ tell [n]
+
+    ... with our previous @tock@ function:
+
+> tock :: StateT Int IO ()
+
+    However, @save@ and @tock@ differ in two ways:
+
+    * @tock@ lacks a 'W.WriterT' layer
+
+    * @save@ has an 'Identity' base monad
+
+    We can mix the two by inserting a 'W.WriterT' layer for @tock@ and
+    generalizing @save@'s base monad:
+
+> import Control.Monad
+> 
+> program ::                   StateT Int (WriterT [Int] IO) ()
+> program = replicateM_ 4 $ do
+>     hoist lift tock
+>         :: (MonadTrans t) => StateT Int (t             IO) ()
+>     hoist (hoist generalize) save
+>         :: (Monad      m) => StateT Int (WriterT [Int] m ) ()
+
+>>> execWriterT (runStateT program 0)
+Tock!
+Tock!
+Tock!
+Tock!
+[1,2,3,4]
+
+-}
+
+{- $embed
+    Suppose we decided to @check@ all 'IOException's using a combination of
+    'try' and 'ErrorT':
+
+> import Control.Exception
+> import Control.Monad.Trans.Class
+> import Control.Monad.Trans.Error
+> 
+> check :: IO a -> ErrorT IOException IO a
+> check io = ErrorT (try io)
+
+    ... but then we forget to use @check@ in one spot, mistakenly using 'lift'
+    instead:
+
+> program :: ErrorT IOException IO ()
+> program = do
+>     str <- lift $ readFile "test.txt"
+>     check $ putStr str
+
+>>> runErrorT program
+*** Exception: test.txt: openFile: does not exist (No such file or directory)
+
+    How could we go back and fix 'program' without modifying its source code?
+
+    Well, @check@ is a monad morphism, but we can't 'hoist' it to modify the
+    base monad because then we get two 'E.ErrorT' layers instead of one:
+
+> hoist check :: (MFunctor t) => t IO a -> t (ErrorT IOException IO) a
+>
+> hoist check program :: ErrorT IOException (ErrorT IOException IO) ()
+
+    We'd prefer to 'embed' all newly generated exceptions in the existing
+    'E.ErrorT' layer:
+
+> embed check :: ErrorT IOException IO a -> ErrorT IOException IO a
+>
+> embed check program :: ErrorT IOException IO ()
+
+    This correctly checks the exceptions that slipped through the cracks:
+
+>>> import Control.Monad.Morph
+>>> runErrorT (embed check program)
+Left test.txt: openFile: does not exist (No such file or directory)
+
+-}
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,25 @@
+Copyright (c) 2013, Gabriel Gonzalez
+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 Gabriel Gonzalez nor the names of other 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/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/mmorph.cabal b/mmorph.cabal
new file mode 100644
--- /dev/null
+++ b/mmorph.cabal
@@ -0,0 +1,24 @@
+Name: mmorph
+Version: 1.0.0
+Cabal-Version: >= 1.8.0.2
+Build-Type: Simple
+License: BSD3
+License-File: LICENSE
+Copyright: 2013 Gabriel Gonzalez
+Author: Gabriel Gonzalez
+Maintainer: Gabriel439@gmail.com
+Bug-Reports: https://github.com/Gabriel439/Haskell-MMorph-Library/issues
+Synopsis: Monad morphisms
+Description: This library provides monad morphism utilities, most commonly used
+    for manipulating monad transformer stacks.
+Category: Control
+Source-Repository head
+    Type: git
+    Location: https://github.com/Gabriel439/Haskell-MMorph-Library
+
+Library
+    Build-Depends:
+        base         >= 4       && < 5  ,
+        transformers >= 0.2.0.0 && < 0.4
+    Exposed-Modules: Control.Monad.Morph
+    GHC-Options: -O2
