Skip to content

Commit

Permalink
Better variable names for ProviderS
Browse files Browse the repository at this point in the history
  • Loading branch information
arybczak committed Oct 6, 2024
1 parent 70e106f commit 93f9db1
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 53 deletions.
20 changes: 12 additions & 8 deletions effectful-core/src/Effectful/Provider.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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
91 changes: 46 additions & 45 deletions effectful-core/src/Effectful/Provider/List.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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

0 comments on commit 93f9db1

Please sign in to comment.