@@ -9,11 +9,11 @@ module Effectful.Internal.Monad
9 ( -- * Monad
9 ( -- * Monad
15− -- ** Running in 'IO'
13+ -- ** Access to the internal representation
17 , unsafeUnliftEff
17 , unsafeUnliftEff
@@ -62,36 +62,45 @@ runEff (Eff m) =
62 -- cleanup actions to run, so the "Dupable" part should also be just fine.
62 -- cleanup actions to run, so the "Dupable" part should also be just fine.
63 unsafeDupablePerformIO $ m =<< emptyEnv
63 unsafeDupablePerformIO $ m =<< emptyEnv
65+----------------------------------------
67+-- | Access underlying 'IO' monad along with the environment.
65unsafeEff :: (Env es -> IO a) -> Eff es a
68unsafeEff :: (Env es -> IO a) -> Eff es a
66unsafeEff m = Eff (oneShot m)
69unsafeEff m = Eff (oneShot m)
71+-- | Access underlying 'IO' monad.
68unsafeEff_ :: IO a -> Eff es a
72unsafeEff_ :: IO a -> Eff es a
69unsafeEff_ m = unsafeEff $ \_ -> m
73unsafeEff_ m = unsafeEff $ \_ -> m
71−----------------------------------------
73-- | A function that runs 'Eff' computations in @m@ (usually a local 'Eff'
75-- | A function that runs 'Eff' computations in @m@ (usually a local 'Eff'
74-- environment or 'IO').
76-- environment or 'IO').
75type RunIn es m = forall r. Eff es r -> m r
77type RunIn es m = forall r. Eff es r -> m r
77-- | Lower 'Eff' computations into 'IO'.
79-- | Lower 'Eff' computations into 'IO'.
81+-- /Note:/ the 'RunIn' argument has to be called from the same thread as
82+-- 'unsafeUnliftEff' ('liftBaseWith' / 'withRunInIO'). Attempting otherwise
83+-- results in a runtime error, because it cannot be done safely in general
84+-- (*). If you need to spawn threads, have a look at "Effectful.Async" or create
85+-- a new 'Eff' environment.
87+-- (*) Consider the following:
91+-- liftBaseWith $ \run -> forkIO $ do
92+-- threadDelay 1000000
98+-- If (1) runs after (2) completed, the State Char effect is no longer in scope,
99+-- but (1) assumes otherwise and things break horribly.
78unsafeUnliftEff :: (RunIn es IO -> IO a) -> Eff es a
100unsafeUnliftEff :: (RunIn es IO -> IO a) -> Eff es a
79unsafeUnliftEff f = unsafeEff $ \es -> do
101unsafeUnliftEff f = unsafeEff $ \es -> do
80 tid0 <- myThreadId
102 tid0 <- myThreadId
81 f $ \(Eff m) -> do
103 f $ \(Eff m) -> do
82− -- The unlifting function can't be safely called from another thread.
84− -- Consider the following:
87− -- liftBaseWith $ \run -> forkIO $ do
88− -- threadDelay 1000000
93− -- If (1) runs after (2) completed, the State Char effect is no longer in
94− -- scope, but (1) assumes otherwise and things break horribly.
95 tid <- myThreadId
104 tid <- myThreadId
96 if tid == tid0
105 if tid == tid0
97 then m es
106 then m es