on master help sign in
Documentation update
commite519afb632a640c5d9d10035b31131e2a424fbfe authorAndrzej Rybczak <andrzej@rybczak.net> dateMon 28 Jun 2021, 19:07 (5 years ago) parent1d35ef1
2 files changed+28−19
src/Effectful/Async.hs+1−1 src/Effectful/Internal/Monad.hs+27−18
src/Effectful/Async.hs+1−1
@@ -67,7 +67,7 @@ import Effectful.Internal.Monad
6767-- | Run 'Eff' computations asynchronously using the @async@ library.
6868--
6969-- /Note:/ thread local state changes in 'Eff' computations run asynchronously
70−-- as 'Async' will not affect the parent thread.
70+-- will not affect the parent thread.
7171data AsyncE :: Effect where
7272 AsyncE :: AsyncE m r
7373
src/Effectful/Internal/Monad.hs+27−18
@@ -9,11 +9,11 @@ module Effectful.Internal.Monad
99 ( -- * Monad
1010 Eff(..)
1111 , runEff
12− , unsafeEff
13− , unsafeEff_
1412
15− -- ** Running in 'IO'
13+ -- ** Access to the internal representation
1614 , RunIn
15+ , unsafeEff
16+ , unsafeEff_
1717 , unsafeUnliftEff
1818
1919 -- * IO
@@ -62,36 +62,45 @@ runEff (Eff m) =
6262 -- cleanup actions to run, so the "Dupable" part should also be just fine.
6363 unsafeDupablePerformIO $ m =<< emptyEnv
6464
65+----------------------------------------
66+
67+-- | Access underlying 'IO' monad along with the environment.
6568unsafeEff :: (Env es -> IO a) -> Eff es a
6669unsafeEff m = Eff (oneShot m)
6770
71+-- | Access underlying 'IO' monad.
6872unsafeEff_ :: IO a -> Eff es a
6973unsafeEff_ m = unsafeEff $ \_ -> m
7074
71−----------------------------------------
72−
7375-- | A function that runs 'Eff' computations in @m@ (usually a local 'Eff'
7476-- environment or 'IO').
7577type RunIn es m = forall r. Eff es r -> m r
7678
7779-- | Lower 'Eff' computations into 'IO'.
80+--
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.
86+--
87+-- (*) Consider the following:
88+--
89+-- @
90+-- runState 'x' $ do
91+-- liftBaseWith $ \run -> forkIO $ do
92+-- threadDelay 1000000
93+-- run $ ... (1)
94+-- ... (2)
95+-- ...
96+-- @
97+--
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.
78100unsafeUnliftEff :: (RunIn es IO -> IO a) -> Eff es a
79101unsafeUnliftEff f = unsafeEff $ \es -> do
80102 tid0 <- myThreadId
81103 f $ \(Eff m) -> do
82− -- The unlifting function can't be safely called from another thread.
83− --
84− -- Consider the following:
85− --
86− -- runState 'x' $ do
87− -- liftBaseWith $ \run -> forkIO $ do
88− -- threadDelay 1000000
89− -- run $ ... (1)
90− -- ... (2)
91− -- ...
92− --
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.
95104 tid <- myThreadId
96105 if tid == tid0
97106 then m es