{-# LANGUAGE ImpredicativeTypes #-} module IdempotentLoweringSpec where import Data.IORef import Polysemy import Polysemy.State import Polysemy.IdempotentLowering import Polysemy.Resource import Test.Hspec runStateInIO :: Member (Lift IO) r => s -> IO (∀ x. Sem (State s ': r) x -> Sem r x) runStateInIO s = do ref <- newIORef s nat $ runStateInIORef ref test :: ( Member Resource r , Member (State Int) r ) => Sem r Int test = do bracket (modify (+1)) (const $ modify (+1)) (const $ modify (+1)) get spec :: Spec spec = describe "Idempotent Lowering" $ do it "should persist an IORef through a bracket" $ do runIt <- nat runM .@! const (runStateInIO 0) .@! liftNat runResourceInIO result <- runIt test result `shouldBe` (3 :: Int)