module Polysemy.Final.IO ( -- * Combinators for Interpreting to the Final Monad interpretFinalGlobal -- * Interpretations for other effects , asyncToIOFinalGlobal , resourceToIOFinalGlobal ) where import qualified Control.Concurrent.Async as A import qualified Control.Exception as X import Polysemy import Polysemy.Final import Polysemy.Final.IO.Internal import Polysemy.Async import Polysemy.Resource ------------------------------------------------------------------------------ -- | 'asyncToIOFinal' implemented using 'interpretFinalGlobal'. -- -- This behaves semantically very much like 'asyncToIO', -- but doesn't need to spin up an interpreter thread, making it more -- efficient (but not any more safe). asyncToIOFinalGlobal :: Member (Final IO) r => Sem (Async ': r) a -> Sem r a asyncToIOFinalGlobal = interpretFinalGlobal $ \case Async m -> do ins <- getInspectorS m' <- runS m liftS $ A.async (inspect ins <$> m') Await a -> liftS (A.wait a) {-# INLINE asyncToIOFinalGlobal #-} ------------------------------------------------------------------------------ -- | 'resourceToIOFinal' implemented using 'interpretFinalGlobal'. -- -- This behaves semantically very much like 'resourceToIO', -- but doesn't need to spin up an interpreter thread, -- making it more efficient (but not any more safe). resourceToIOFinalGlobal :: Member (Final IO) r => Sem (Resource ': r) a -> Sem r a resourceToIOFinalGlobal = interpretFinalGlobal $ \case Bracket alloc dealloc use -> do a <- runS alloc d <- bindS dealloc u <- bindS use pure $ X.bracket a d u BracketOnError alloc dealloc use -> do a <- runS alloc d <- bindS dealloc u <- bindS use pure $ X.bracketOnError a d u {-# INLINE resourceToIOFinalGlobal #-}