{-# LANGUAGE FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, TypeOperators, UndecidableInstances #-}
module Control.Carrier.Error.Either
(
runError
, ErrorC(..)
, module Control.Effect.Error
) where
import Control.Algebra
import Control.Applicative (Alternative(..))
import Control.Effect.Error
import Control.Monad (MonadPlus(..))
import qualified Control.Monad.Fail as Fail
import Control.Monad.Fix
import Control.Monad.IO.Class
import Control.Monad.Trans.Class
import Control.Monad.Trans.Except
runError :: ErrorC exc m a -> m (Either exc a)
runError (ErrorC m) = runExceptT m
newtype ErrorC e m a = ErrorC (ExceptT e m a)
deriving (Applicative, Functor, Monad, Fail.MonadFail, MonadFix, MonadIO, MonadTrans)
instance (Alternative m, Monad m) => Alternative (ErrorC e m) where
empty = ErrorC (ExceptT empty)
{-# INLINE empty #-}
ErrorC (ExceptT l) <|> ErrorC (ExceptT r) = ErrorC (ExceptT (l <|> r))
{-# INLINE (<|>) #-}
instance (Alternative m, Monad m) => MonadPlus (ErrorC e m)
instance (Algebra sig m, Effect sig) => Algebra (Error e :+: sig) (ErrorC e m) where
alg = ErrorC . alg . handleCoercible
{-# INLINE alg #-}