polysemy-resume-0.3.0.0: test/Polysemy/Resume/HigherOrderTest.hs
{-# options_ghc -fplugin=Polysemy.Plugin #-}
module Polysemy.Resume.HigherOrderTest where
import Control.Concurrent.STM (newTVarIO, readTVarIO)
import Polysemy.Test (UnitTest, runTestAuto, (===))
import Polysemy.Resume (type (!!))
import Polysemy.Resume.Data.Stop (stop)
import Polysemy.Resume.Resumable (interpretResumableH)
import Polysemy.Resume.Resume (resume)
data Eff :: Effect where
Nest :: m a -> Eff m a
Result :: Eff m Int
makeSem ''Eff
data Off :: Effect where
Off :: Off m Int
makeSem ''Off
interpretEffNested ::
InterpreterFor (Eff !! Text) r
interpretEffNested =
interpretResumableH \case
Nest _ ->
stop "no"
Result ->
pureT 2
interpretEff ::
InterpreterFor (Eff !! Text) r
interpretEff =
interpretResumableH \case
Nest ma -> do
sem <- runT ma
raise (interpretEffNested sem)
Result ->
pureT 1
interpretEffFinally ::
Members [Resource, AtomicState Int] r =>
InterpreterFor (Eff !! Text) r
interpretEffFinally sem =
interpretEff (finally sem log)
where
log =
atomicModify (1 +)
-- interpretOff ::
-- Member (Eff !! Text) r =>
-- InterpreterFor (Off !! Text) r
-- interpretOff sem =
-- restop (nest $ interpretResumable (\Off -> result) (raiseUnder sem))
test_switchInterpreter :: UnitTest
test_switchInterpreter =
runTestAuto do
tv <- embed (newTVarIO 0)
(2 ===) =<< runAtomicStateTVar tv (interpretEffFinally (resume (nest (result >> result)) \ _ -> pure 3))
(1 ===) =<< embed (readTVarIO tv)
(3 ===) =<< interpretEff (resume (nest (nest result)) \ _ -> pure 3)
(1 ===) =<< interpretEff (resume result \ _ -> pure 3)
-- (2 ===) =<< interpretEff (interpretOff (resume off \ _ -> pure 3))