Skip to content

Commit

Permalink
Allow access to handler effects in the local environment
Browse files Browse the repository at this point in the history
  • Loading branch information
arybczak committed Nov 29, 2023
1 parent 87955a8 commit 0bfb755
Showing 1 changed file with 30 additions and 2 deletions.
32 changes: 30 additions & 2 deletions effectful-core/src/Effectful/Dispatch/Dynamic.hs
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,17 @@ module Effectful.Dispatch.Dynamic
, localLiftUnlift
, localLiftUnliftIO

-- *** Utils
-- *** Misc
, localSeqHandle
, SharedSuffix

-- * Re-exports
, HasCallStack
) where

import Control.Monad
import Control.Monad.IO.Unlift
import Data.Primitive.PrimArray
import GHC.Stack (HasCallStack)
import GHC.TypeLits

Expand Down Expand Up @@ -726,7 +729,32 @@ localLiftUnliftIO (LocalEnv les) strategy k = case strategy of
ConcUnlift p l -> liftIO $ concUnliftIO les p l $ k unsafeEff_

----------------------------------------
-- Utils
-- Misc

localSeqHandle
:: (e :> es, SharedSuffix es handlerEs)
=> LocalEnv localEs handlerEs
-> ((forall r. Eff (e : localEs) r -> Eff localEs r) -> Eff es a)
-> Eff es a
localSeqHandle (LocalEnv les) k = unsafeEff $ \es -> do
eles <- copyRef es les
seqUnliftIO eles $ \unlift -> (`unEff` es) $ k $ unsafeEff_ . unlift

copyRef
:: forall e es localEs. e :> es
=> Env es
-> Env localEs
-> IO (Env (e : localEs))
copyRef (Env hoffset hrefs hstorage) (Env offset refs0 storage) = do
when (hstorage /= storage) $ do
error "storages do not match"
let size = sizeofPrimArray refs0 - offset
i = 2 * reifyIndex @e @es
mrefs <- newPrimArray (size + 2)
copyPrimArray mrefs 0 hrefs (hoffset + i) 2
copyPrimArray mrefs 2 refs0 offset size
refs <- unsafeFreezePrimArray mrefs
pure $ Env 0 refs storage

-- | Require that both effect stacks share an opaque suffix.
--
Expand Down

0 comments on commit 0bfb755

Please sign in to comment.