diff --git a/EitherT.cabal b/EitherT.cabal
new file mode 100644
--- /dev/null
+++ b/EitherT.cabal
@@ -0,0 +1,15 @@
+Name:                EitherT
+Version:             0.0.1
+Synopsis:            EitherT monad transformer
+Description:         Support for computations with informative failures.
+License:             BSD3
+License-file:        LICENSE
+Category:            Control
+Author:              Eyal Lotem <eyal.lotem+hackage@gmail.com>
+Maintainer:          Eyal Lotem <eyal.lotem+hackage@gmail.com>
+Stability:           experimental
+Build-Type:          Simple
+HS-Source-Dirs:      src
+Build-Depends:       base >= 4 && < 5, mtl
+Exposed-modules:     Control.Monad.Either
+ghc-options:         -Wall 
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,26 @@
+EitherT monad transformer.
+Copyright 2007 Eyal Lotem.  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.
+  * The names of this library's contributors may not 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 OWNER 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/src/Control/Monad/Either.hs b/src/Control/Monad/Either.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/Either.hs
@@ -0,0 +1,59 @@
+{-# OPTIONS -Wall -O2 -fno-warn-orphans #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+-- Exports Applicative/Monad instances for Either
+module Control.Monad.Either(EitherT(..), left) where
+
+import Control.Monad(liftM)
+import Control.Monad.Trans(MonadTrans(..))
+import Control.Monad.Instances()
+import Control.Monad.Trans(MonadIO(..))
+import Control.Applicative(Applicative(..), liftA2)
+
+newtype EitherT l m a = EitherT { runEitherT :: m (Either l a) }
+inEitherT0 :: m (Either l a) -> EitherT l m a
+inEitherT0 = EitherT
+inEitherT1 :: (m (Either l a) -> m (Either l b)) ->
+              EitherT l m a -> EitherT l m b
+inEitherT1 f = inEitherT0 . f . runEitherT
+inEitherT2 :: (m (Either l a) -> m (Either l b) -> m (Either l c)) ->
+              EitherT l m a -> EitherT l m b -> EitherT l m c
+inEitherT2 f = inEitherT1 . f . runEitherT
+
+left :: Monad m => l -> EitherT l m a
+left = EitherT . return . Left
+
+instance Monad m => Monad (EitherT l m) where
+  -- We can't support "fail" because we don't have a
+  -- (String -> l). But we can at least make it a Left, with the error inside
+  -- it as a pure exception.
+  fail = EitherT . return . Left . error
+  return = EitherT . return . Right
+  EitherT x >>= f = EitherT $ do
+    res <- x
+    case res of
+      Right r -> runEitherT . f $ r
+      Left l -> return (Left l)
+
+instance MonadTrans (EitherT l) where
+  lift = EitherT . liftM Right
+
+instance Applicative (Either l) where
+  pure = Right
+  Right f <*> Right x = Right (f x)
+  Left e <*> _ = Left e
+  _ <*> Left e = Left e
+
+instance Monad (Either l) where
+  return = pure
+  Right x >>= f = f x
+  Left e >>= _ = Left e
+
+instance Functor f => Functor (EitherT l f) where
+  fmap = inEitherT1 . fmap . fmap
+instance Applicative f => Applicative (EitherT l f) where
+  pure = inEitherT0 . pure . pure
+  (<*>) = inEitherT2 . liftA2 . liftA2 $ id
+
+instance (MonadIO m) => MonadIO (EitherT l m) where
+  liftIO = lift . liftIO
