{-|
This modules provides newtypes which flip the type variables of 'Either'
and 'EitherT' to access the symmetric monad over the opposite type variable.
This module provides the following simple benefits to the casual user:
* A type-class free alternative to @MonadError@
* No @UndecidableInstances@ or any other extensions, for that matter
* A more powerful 'catchE' statement that allows you to change the type of
error value returned
More advanced users can take advantage of the fact that 'EitherR' and
'EitherRT' define an entirely symmetric \"success monad\" where
error-handling computations are the default and successful results terminate
the monad. This allows you to chain error-handlers and pass around values
other than exceptions until you can finally recover from the error:
> runEitherRT $ do
> e2 <- ioExceptionHandler e1
> bool <- arithmeticExceptionhandler e2
> when bool $ lift $ putStrLn "DEBUG: Arithmetic handler did something"
If any of the above error handlers 'succeed', no other handlers are tried.
-}moduleData.EitherR(EitherR(..),-- ** Operations in the EitherR monadsucceed,-- ** Conversions to the Either monadthrowE,catchE,handleE,fmapL,-- * EitherRTEitherRT(..),-- ** Operations in the EitherRT monadright,succeedT,-- ** Conversions to the EitherT monadleft,throwT,catchT,handleT,fmapLT)whereimportControl.ApplicativeimportControl.MonadimportControl.Monad.Trans.ClassimportControl.Monad.Trans.Either{-|
If \"@Either e r@\" is the error monad, then \"@EitherR r e@\" is the
corresponding success monad, where:
* 'return' is 'throwE'.
* ('>>=') is 'catchE'.
* Successful results abort the computation
-}newtypeEitherRre=EitherR{runEitherR::Eitherer}instanceFunctor(EitherRr)wherefmap=liftMinstanceApplicative(EitherRr)wherepure=return(<*>)=apinstanceMonad(EitherRr)wherereturn=EitherR.Left(EitherRm)>>=f=EitherR$casemofLefte->runEitherR(fe)Rightr->Rightr-- | Complete error handling, returning a resultsucceed::r->EitherRresucceed=EitherR.return-- | 'throwE' in the error monad corresponds to 'return' in the success monadthrowE::e->EithererthrowE=runEitherR.return-- | 'catchE' in the error monad corresponds to ('>>=') in the success monadcatchE::Eitherar->(a->Eitherbr)->Eitherbre`catchE`f=runEitherR$(EitherRe)>>=(EitherR.f)-- | 'catchE' with the arguments flippedhandleE::(a->Eitherbr)->Eitherar->EitherbrhandleE=flipcatchE-- | Map a function over the 'Left' value of an 'Either'fmapL::(a->b)->Eitherar->EitherbrfmapLf=runEitherR.fmapf.EitherR-- | 'EitherR' converted into a monad transformernewtypeEitherRTrme=EitherRT{runEitherRT::EitherTemr}instance(Monadm)=>Functor(EitherRTrm)wherefmap=liftMinstance(Monadm)=>Applicative(EitherRTrm)wherepure=return(<*>)=apinstance(Monadm)=>Monad(EitherRTrm)wherereturn=EitherRT.leftm>>=f=EitherRT$EitherT$dox<-runEitherT$runEitherRTmrunEitherT$runEitherRT$casexofLefte->feRightr->rightrinstanceMonadTrans(EitherRTr)wherelift=EitherRT.EitherT.liftMLeft-- | The dual to 'left' and synonymous with 'succeedT'right::(Monadm)=>r->EitherRTrmeright=EitherRT.return-- | Complete error handling, returning a resultsucceedT::(Monadm)=>r->EitherRTrmesucceedT=right-- | Synonym for 'throwT'left::(Monadm)=>e->EitherTemrleft=throwT-- | 'throwT' in the error monad corresponds to 'return' in the success monadthrowT::(Monadm)=>e->EitherTemrthrowT=runEitherRT.return-- | 'catchT' in the error monad corresponds to ('>>=') in the success monadcatchT::(Monadm)=>EitherTamr->(a->EitherTbmr)->EitherTbmre`catchT`f=runEitherRT$(EitherRTe)>>=(EitherRT.f)-- | 'catchT' with the arguments flippedhandleT::(Monadm)=>(a->EitherTbmr)->EitherTamr->EitherTbmrhandleT=flipcatchT-- | Map a function over the 'Left' value of an 'EitherT'fmapLT::(Monadm)=>(a->b)->EitherTamr->EitherTbmrfmapLTf=runEitherRT.fmapf.EitherRT