{-# LANGUAGE PartialTypeSignatures #-} {-# OPTIONS_GHC -Wno-orphans #-} {-# OPTIONS_GHC -fplugin=Polysemy.Plugin #-} module EquivSpec where import Data.IORef (newIORef) import Data.Proxy (Proxy) import Polysemy import Polysemy.Check import Polysemy.State import Test.Hspec import Test.Hspec.QuickCheck import Test.QuickCheck spec :: Spec spec = do prop "Pure state is equivalent to IO state" $ do s0 <- arbitrary pure $ prepropEquivalent @'[State Int] @Int (runPureState s0) (runIOState s0) $ \(_ :: Proxy r) -> do SomeAction e1 <- arbitraryAction @(State Int) @r SomeAction e2 <- arbitraryAction @(State Int) @r e3 <- arbitraryActionOfType @(State Int) @Int @r pure $ send e1 >> send e2 >> send e3 runPureState :: Int -> Sem '[State Int] a -> IO a runPureState s = pure . run . evalState s runIOState :: Int -> Sem '[State Int, Embed IO] a -> IO (a) runIOState s sem = do ref <- newIORef s runM . runStateIORef ref $ sem