packages feed

registry-0.3.2.1: src/Data/Registry/RIO.hs

-- | Utilities for working with ResourceT IO
module Data.Registry.RIO where

import Control.Monad.Trans.Resource
import Data.Registry.Make
import Data.Registry.Registry
import Data.Registry.Solver
import Protolude

-- | Type alias for ResourceT IO
type RIO = ResourceT IO

-- | This function must be used to run services involving a top component
--   It creates an application of type a and which can return a result of type b.
--
--   We also make sure that all effects are memoized by calling `memoizeAll` on the Registry here!
withRegistry ::
  forall a b ins out m.
  (Typeable a, Contains (RIO a) out, Solvable ins out, MonadIO m, MemoizedActions out) =>
  Registry ins out ->
  (a -> IO b) ->
  m b
withRegistry registry f = liftIO $
  runResourceT (runRegistryT @a registry >>= liftIO . f)

-- | This can be used if you want to insert the component creation inside
--   another action managed with ResourceT. Or if you want to call runResourceT yourself later
runRegistryT ::
  forall a ins out .
  (Typeable a, Contains (RIO a) out, Solvable ins out, MemoizedActions out) =>
  Registry ins out ->
  ResourceT IO a
runRegistryT registry =
  liftIO (memoizeAll @RIO registry) >>= make @(RIO a)