{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Control.Carrier.Throw.Either
(
runThrow
, ThrowC(ThrowC)
, module Control.Effect.Throw
) where
import Control.Algebra
import Control.Applicative (Alternative)
import Control.Carrier.Error.Either
import Control.Effect.Throw
import Control.Monad (MonadPlus)
import Control.Monad.Fail as Fail
import Control.Monad.Fix
import Control.Monad.IO.Class
import Control.Monad.Trans.Class
runThrow :: ThrowC e m a -> m (Either e a)
runThrow (ThrowC m) = runError m
{-# INLINE runThrow #-}
newtype ThrowC e m a = ThrowC { runThrowC :: ErrorC e m a }
deriving (Alternative, Applicative, Functor, Monad, Fail.MonadFail, MonadFix, MonadIO, MonadPlus, MonadTrans)
instance Algebra sig m => Algebra (Throw e :+: sig) (ThrowC e m) where
alg hdl sig ctx = case sig of
L (Throw e) -> ThrowC (throwError e)
R other -> ThrowC (alg (runThrowC . hdl) (R other) ctx)
{-# INLINE alg #-}