module Polysemy.Final.Error
(
module Polysemy.Error
, module Polysemy.Final
, runErrorInIOFinal
) where
import Control.Exception hiding (throw, catch)
import qualified Control.Exception as X
import Data.Typeable (Typeable, typeRep)
import Polysemy
import Polysemy.Final
import Polysemy.Error
runErrorInIOFinal
:: ( Typeable e
, Member (Final IO) r
)
=> Sem (Error e ': r) a
-> Sem r (Either e a)
runErrorInIOFinal sem = withStrategic $ do
m' <- runS (runErrorAsExcFinal sem)
s <- getInitialStateS
pure $
either
((<$ s) . Left . unwrapExc)
(fmap Right)
<$> try m'
{-# INLINE runErrorInIOFinal #-}
runErrorAsExcFinal
:: forall e r a
. ( Typeable e
, Member (Final IO) r
)
=> Sem (Error e ': r) a
-> Sem r a
runErrorAsExcFinal = interpretFinal $ \case
Throw e -> pure $ throwIO $ WrappedExc e
Catch m h -> do
m' <- runS m
h' <- bindS h
s <- getInitialStateS
pure $ X.catch m' $ \(se :: WrappedExc e) ->
h' (unwrapExc se <$ s)
{-# INLINE runErrorAsExcFinal #-}
newtype WrappedExc e = WrappedExc { unwrapExc :: e }
deriving (Typeable)
instance Typeable e => Show (WrappedExc e) where
show = mappend "WrappedExc: " . show . typeRep
instance (Typeable e) => Exception (WrappedExc e)