{-# 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