@@ -10,6 +10,7 @@ module Effectful.Internal.Monad
11 , impureEff
11 , impureEff
12 , impureEff_
12 , impureEff_
@@ -52,6 +53,19 @@ impureEff m = Eff (oneShot m)
52impureEff_ :: IO a -> Eff es a
53impureEff_ :: IO a -> Eff es a
53impureEff_ m = impureEff $ \_ -> m
54impureEff_ m = impureEff $ \_ -> m
56+-- | Run 'Eff' computations in 'IO'.
57+impureUnliftEff :: ((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
58+impureUnliftEff f = impureEff $ \es -> do
62+ -- If the lifting function is called from a different thread, we need to
63+ -- clone the environment. Otherwise multiple threads will attempt to modify
64+ -- it in different ways and things will break horribly.
67+ else m =<< cloneEnv es
55----------------------------------------
69----------------------------------------
@@ -114,24 +128,11 @@ instance IOE :> es => MonadBase IO (Eff es) where
115instance IOE :> es => MonadBaseControl IO (Eff es) where
129instance IOE :> es => MonadBaseControl IO (Eff es) where
116 type StM (Eff es) a = a
130 type StM (Eff es) a = a
117− liftBaseWith = runInIO
131+ liftBaseWith = impureUnliftEff
118 restoreM = pure
132 restoreM = pure
120instance IOE :> es => MonadUnliftIO (Eff es) where
134instance IOE :> es => MonadUnliftIO (Eff es) where
121− withRunInIO = runInIO
135+ withRunInIO = impureUnliftEff
123−-- | Run 'Eff' computations in 'IO'.
124−runInIO :: ((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
125−runInIO f = impureEff $ \es -> do
129− -- If the lifting function is called from a different thread, we need to
130− -- clone the environment. Otherwise multiple threads will attempt to modify
131− -- it in different ways and things will break horribly.
134− else m =<< cloneEnv es
136----------------------------------------
137----------------------------------------
137-- Helpers
138-- Helpers