{-# LANGUAGE FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, TypeOperators, UndecidableInstances #-}
module Control.Carrier.Fail.Either
(
runFail
, FailC(..)
, module Control.Effect.Fail
) where
import Control.Algebra
import Control.Applicative (Alternative(..))
import Control.Carrier.Throw.Either
import Control.Effect.Fail
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
runFail :: FailC m a -> m (Either String a)
runFail (FailC m) = runThrow m
newtype FailC m a = FailC (ThrowC String m a)
deriving (Alternative, Applicative, Functor, Monad, MonadFix, MonadIO, MonadPlus, MonadTrans)
instance (Algebra sig m, Effect sig) => Fail.MonadFail (FailC m) where
fail = send . Fail
{-# INLINE fail #-}
instance (Algebra sig m, Effect sig) => Algebra (Fail :+: sig) (FailC m) where
alg = FailC . alg . handleCoercible
{-# INLINE alg #-}