diff --git a/effectful-core/src/Effectful/Provider.hs b/effectful-core/src/Effectful/Provider.hs index ff8f342..f5c5145 100644 --- a/effectful-core/src/Effectful/Provider.hs +++ b/effectful-core/src/Effectful/Provider.hs @@ -125,8 +125,8 @@ type instance DispatchOf (Provider e input f) = Static NoSideEffects data instance StaticRep (Provider e input f) where Provider - :: !(Env providerEs) - -> !(forall r. HasCallStack => input -> Eff (e : providerEs) r -> Eff providerEs (f r)) + :: !(Env handlerEs) + -> !(forall r. HasCallStack => input -> Eff (e : handlerEs) r -> Eff handlerEs (f r)) -> StaticRep (Provider e input f) -- | Run the 'Provider' effect with a given effect handler. @@ -171,8 +171,8 @@ provideWith -> Eff (e : es) a -> Eff es (f a) provideWith input action = unsafeEff $ \es -> do - Provider providerEs handler <- getEnv es - (`unEff` providerEs) + Provider handlerEs handler <- getEnv es + (`unEff` handlerEs) -- Corresponds to thawCallStack in runProvider. . withFrozenCallStack handler input . unsafeEff $ \eProviderEs -> do @@ -195,17 +195,21 @@ provideWith_ input = adapt . provideWith input -- Helpers relinkProvider :: Relinker StaticRep (Provider e input f) -relinkProvider = Relinker $ \relink (Provider providerEs run) -> do - newHandlerEs <- relink providerEs +relinkProvider = Relinker $ \relink (Provider handlerEs run) -> do + newHandlerEs <- relink handlerEs pure $ Provider newHandlerEs run -copyRef :: HasCallStack => Env (e : providerEs) -> Env es -> IO (Env (e : es)) +copyRef + :: HasCallStack + => Env (e : handlerEs) + -> Env es + -> IO (Env (e : es)) copyRef (Env hoffset hrefs hstorage) (Env offset refs0 storage) = do when (hstorage /= storage) $ do error "storages do not match" let size = sizeofPrimArray refs0 - offset mrefs <- newPrimArray (size + 1) - copyPrimArray mrefs 0 hrefs hoffset 1 + writePrimArray mrefs 0 $ indexPrimArray hrefs hoffset copyPrimArray mrefs 1 refs0 offset size refs <- unsafeFreezePrimArray mrefs pure $ Env 0 refs storage diff --git a/effectful-core/src/Effectful/Provider/List.hs b/effectful-core/src/Effectful/Provider/List.hs index 7e7add2..75b2140 100644 --- a/effectful-core/src/Effectful/Provider/List.hs +++ b/effectful-core/src/Effectful/Provider/List.hs @@ -38,31 +38,32 @@ import Effectful.Internal.Effect import Effectful.Internal.Env (Env(..)) import Effectful.Internal.Utils --- | Provide a way to run a handler of a @list@ of effects with a given @input@. +-- | Provide a way to run a handler of multiple @providedEs@ with a given +-- @input@. -- -- /Note:/ @f@ can be used to alter the return type of the handler. If that's -- unnecessary, use 'ProviderList_'. -data ProviderList (list :: [Effect]) (input :: Type) (f :: Type -> Type) :: Effect +data ProviderList (providedEs :: [Effect]) (input :: Type) (f :: Type -> Type) :: Effect -- | A restricted variant of 'ProviderList' with unchanged return type of the -- handler. -type ProviderList_ list input = ProviderList list input Identity +type ProviderList_ providedEs input = ProviderList providedEs input Identity -type instance DispatchOf (ProviderList list input f) = Static NoSideEffects +type instance DispatchOf (ProviderList providedEs input f) = Static NoSideEffects -data instance StaticRep (ProviderList list input f) where +data instance StaticRep (ProviderList providedEs input f) where ProviderList - :: KnownEffects list - => !(Env providerEs) - -> !(forall r. HasCallStack => input -> Eff (list ++ providerEs) r -> Eff providerEs (f r)) - -> StaticRep (ProviderList list input f) + :: KnownEffects providedEs + => !(Env handlerEs) + -> !(forall r. HasCallStack => input -> Eff (providedEs ++ handlerEs) r -> Eff handlerEs (f r)) + -> StaticRep (ProviderList providedEs input f) -- | Run the 'ProviderList' effect with a given handler. runProviderList - :: (HasCallStack, KnownEffects list) - => (forall r. HasCallStack => input -> Eff (list ++ es) r -> Eff es (f r)) + :: (HasCallStack, KnownEffects providedEs) + => (forall r. HasCallStack => input -> Eff (providedEs ++ es) r -> Eff es (f r)) -- ^ The handler. - -> Eff (ProviderList list input f : es) a + -> Eff (ProviderList providedEs input f : es) a -> Eff es a runProviderList providerList m = unsafeEff $ \es0 -> do inlineBracket @@ -77,55 +78,55 @@ runProviderList providerList m = unsafeEff $ \es0 -> do -- | Run the 'Provider' effect with a given handler that doesn't change its -- return type. runProviderList_ - :: (HasCallStack, KnownEffects list) - => (forall r. HasCallStack => input -> Eff (list ++ es) r -> Eff es r) + :: (HasCallStack, KnownEffects providedEs) + => (forall r. HasCallStack => input -> Eff (providedEs ++ es) r -> Eff es r) -- ^ The handler. - -> Eff (ProviderList_ list input : es) a + -> Eff (ProviderList_ providedEs input : es) a -> Eff es a runProviderList_ providerList = runProviderList $ \input -> coerce . providerList input -- | Run the handler. provideList - :: forall list f es a - . (HasCallStack, ProviderList list () f :> es) - => Eff (list ++ es) a + :: forall providedEs f es a + . (HasCallStack, ProviderList providedEs () f :> es) + => Eff (providedEs ++ es) a -> Eff es (f a) -provideList = provideListWith @list () +provideList = provideListWith @providedEs () -- | Run the handler with unchanged return type. provideList_ - :: forall list es a - . (HasCallStack, ProviderList_ list () :> es) - => Eff (list ++ es) a + :: forall providedEs es a + . (HasCallStack, ProviderList_ providedEs () :> es) + => Eff (providedEs ++ es) a -> Eff es a -provideList_ = provideListWith_ @list () +provideList_ = provideListWith_ @providedEs () -- | Run the handler with a given input. provideListWith - :: forall list input f es a - . (HasCallStack, ProviderList list input f :> es) + :: forall providedEs input f es a + . (HasCallStack, ProviderList providedEs input f :> es) => input -- ^ The input to the handler. - -> Eff (list ++ es) a + -> Eff (providedEs ++ es) a -> Eff es (f a) provideListWith input action = unsafeEff $ \es -> do - ProviderList (providerEs :: Env providerEs) providerList <- do - getEnv @(ProviderList list input f) es - (`unEff` providerEs) + ProviderList (handlerEs :: Env handlerEs) providerList <- do + getEnv @(ProviderList providedEs input f) es + (`unEff` handlerEs) -- Corresponds to a thawCallStack in runProviderList. . withFrozenCallStack providerList input . unsafeEff $ \eHandlerEs -> do - unEff action =<< copyRefs @list @providerEs eHandlerEs es + unEff action =<< copyRefs @providedEs @handlerEs eHandlerEs es -- | Run the handler that doesn't change its return type with a given input. provideListWith_ - :: forall list input es a - . (HasCallStack, ProviderList_ list input :> es) + :: forall providedEs input es a + . (HasCallStack, ProviderList_ providedEs input :> es) => input -- ^ The input to the handler. - -> Eff (list ++ es) a + -> Eff (providedEs ++ es) a -> Eff es a -provideListWith_ input = adapt . provideListWith @list input +provideListWith_ input = adapt . provideListWith @providedEs input where adapt :: Eff es (Identity a) -> Eff es a adapt = coerce @@ -134,23 +135,23 @@ provideListWith_ input = adapt . provideListWith @list input -- Helpers relinkProviderList :: Relinker StaticRep (ProviderList e input f) -relinkProviderList = Relinker $ \relink (ProviderList providerEs run) -> do - newHandlerEs <- relink providerEs +relinkProviderList = Relinker $ \relink (ProviderList handlerEs run) -> do + newHandlerEs <- relink handlerEs pure $ ProviderList newHandlerEs run copyRefs - :: forall list providerEs es - . (HasCallStack, KnownEffects list) - => Env (list ++ providerEs) + :: forall providedEs handlerEs es + . (HasCallStack, KnownEffects providedEs) + => Env (providedEs ++ handlerEs) -> Env es - -> IO (Env (list ++ es)) + -> IO (Env (providedEs ++ es)) copyRefs (Env hoffset hrefs hstorage) (Env offset refs0 storage) = do when (hstorage /= storage) $ do error "storages do not match" - let size = sizeofPrimArray refs0 - offset - listSize = knownEffectsLength @list - mrefs <- newPrimArray (size + listSize) - copyPrimArray mrefs 0 hrefs hoffset listSize - copyPrimArray mrefs listSize refs0 offset size + let providedEsSize = knownEffectsLength @providedEs + esSize = sizeofPrimArray refs0 - offset + mrefs <- newPrimArray (providedEsSize + esSize) + copyPrimArray mrefs 0 hrefs hoffset providedEsSize + copyPrimArray mrefs providedEsSize refs0 offset esSize refs <- unsafeFreezePrimArray mrefs pure $ Env 0 refs storage