{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE MonoLocalBinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
module Control.Eff.ExceptionExtra
( try
, liftRethrow
, runErrorRethrowIO
, module X
)
where
import Control.Monad ( (>=>) )
import qualified Control.Exception as Exc
import Control.Eff
import Control.Eff.Lift
import Control.Eff.Exception as X
try :: forall e r a . Member (Exc e) r => Eff r a -> Eff r (Either e a)
try e = catchError (Right <$> e) (return . Left)
liftRethrow
:: forall e r a
. (Exc.Exception e, SetMember Lift (Lift IO) r, Member (Exc e) r)
=> (Exc.SomeException -> e)
-> IO a
-> Eff r a
liftRethrow liftE m = lift (Exc.try m) >>= either (throwError . liftE) return
runErrorRethrowIO
:: forall e r a
. (Exc.Exception e, SetMember Lift (Lift IO) r)
=> Eff (Exc e ': r) a
-> Eff r a
runErrorRethrowIO = runError >=> either (Exc.throw . Exc.SomeException) return