{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, TypeOperators, UndecidableInstances #-}
module Control.Effect.Fail
( Fail(..)
, MonadFail(..)
, runFail
, FailC(..)
) where
import Control.Effect.Carrier
import Control.Effect.Fail.Internal
import Control.Effect.Internal
import Control.Effect.Sum
import Control.Monad.Fail
runFail :: (Carrier sig m, Effect sig) => Eff (FailC m) a -> m (Either String a)
runFail = runFailC . interpret
newtype FailC m a = FailC { runFailC :: m (Either String a) }
instance (Carrier sig m, Effect sig) => Carrier (Fail :+: sig) (FailC m) where
ret a = FailC (ret (Right a))
eff = FailC . handleSum (eff . handleEither runFailC) (\ (Fail s) -> ret (Left s))