{-#LANGUAGE LambdaCase,TemplateHaskell,KindSignatures,DataKinds,TypeFamilies#-} import Effectful import Effectful.Dispatch.Dynamic import Data.Kind(Type) import Effectful.State.Static.Shared data Event e m a where RegisterHandler :: (e -> m ()) -> Event e m () RaiseEvent :: e -> Event e m () registerHandler ::Event e :> es => (e -> Eff es ()) -> Eff es () registerHandler = send . RegisterHandler raiseEvent :: Event e :> es => e -> Eff es () raiseEvent = send . RaiseEvent type instance DispatchOf (Event e) = 'Dynamic runEvent ::forall e es a. Eff (Event e ': es) a -> Eff es a runEvent = reinterpret (evalState ([]::[e -> Eff es ()])) $ \env -> \case (RegisterHandler act) -> localUnlift env (ConcUnlift Persistent Unlimited) $ \unlift -> modify @([e -> Eff es ()]) ((unlift . act) :)