EitherT (empty) → 0.0.1
raw patch · 4 files changed
+102/−0 lines, 4 filesdep +basedep +mtlsetup-changed
Dependencies added: base, mtl
Files
- EitherT.cabal +15/−0
- LICENSE +26/−0
- Setup.hs +2/−0
- src/Control/Monad/Either.hs +59/−0
+ EitherT.cabal view
@@ -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
+ LICENSE view
@@ -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.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Control/Monad/Either.hs view
@@ -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