{-# LANGUAGE TemplateHaskell #-}
module Polysemy.Floodgate
(
Floodgate (..)
, hold
, release
, runFloodgate
, runFloodgateDry
) where
import Control.Monad
import GHC.Types
import Polysemy
import Polysemy.State
import Unsafe.Coerce
data Floodgate m a where
Hold :: m () -> Floodgate m ()
Release :: Floodgate m ()
makeSem ''Floodgate
runFloodgate
:: Sem (Floodgate ': r) a
-> Sem r a
runFloodgate = fmap snd . runState @[Any] [] . reinterpretH
( \case
Hold m -> do
m' <- fmap void $ runT m
modify (unsafeCoerce @_ @Any (raise $ runFloodgate m') :)
getInitialStateT
Release -> do
ms' <- gets @[Any] (fmap unsafeCoerce . reverse)
sequence_ ms'
getInitialStateT
)
runFloodgateDry
:: Sem (Floodgate ': r) a
-> Sem r a
runFloodgateDry m = runFloodgate $ m <* release