@@ -58,17 +58,18 @@ module Effectful.Internal.Monad
5858import Control.Applicative (liftA2)
5959import Control.Concurrent (myThreadId)
6060import Control.Exception
61−import Control.Monad.Base
6261import Control.Monad.Fix
6362import Control.Monad.IO.Class
64−import Control.Monad.IO.Unlift
6563import Control.Monad.Primitive
66−import Control.Monad.Trans.Control
6764import Data.Unique
6865import GHC.Exts (oneShot)
6966import GHC.IO (IO(..))
67+import GHC.Stack (HasCallStack)
7068import System.IO.Unsafe (unsafeDupablePerformIO)
69+import qualified Control.Monad.Base as M
7170import qualified Control.Monad.Catch as E
71+import qualified Control.Monad.IO.Unlift as M
72+import qualified Control.Monad.Trans.Control as M
7273
7374import Effectful.Internal.Effect
7475import Effectful.Internal.Env
@@ -143,13 +144,18 @@ unsafeEff_ m = unsafeEff $ \_ -> m
143144-- /Note:/ the 'IO' operation must not run its argument in a separate thread,
144145-- attempting to do so will result in a runtime error.
145146unsafeWithLiftMapIO
146− :: ((forall a b localEs. (IO a -> IO b) -> Eff localEs a -> Eff localEs b) -> Eff es r)
147+ :: HasCallStack
148+ => ((forall a b localEs. (IO a -> IO b) -> Eff localEs a -> Eff localEs b) -> Eff es r)
147149 -> Eff es r
148150unsafeWithLiftMapIO k = k $ \mapIO m -> unsafeEff $ \es -> do
149151 unsafeSeqUnliftEff es $ \unlift -> mapIO $ unlift m
150152
151153-- | Lower 'Eff' operations into 'IO' ('SeqUnlift').
152−unsafeSeqUnliftEff :: Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
154+unsafeSeqUnliftEff
155+ :: HasCallStack
156+ => Env es
157+ -> ((forall r. Eff es r -> IO r) -> IO a)
158+ -> IO a
153159unsafeSeqUnliftEff es k = do
154160 tid0 <- myThreadId
155161 k $ \m -> do
@@ -162,7 +168,8 @@ unsafeSeqUnliftEff es k = do
162168
163169-- | Lower 'Eff' operations into 'IO' ('ConcUnlift').
164170unsafeConcUnliftEff
165− :: Env es
171+ :: HasCallStack
172+ => Env es
166173 -> Persistence
167174 -> Limit
168175 -> ((forall r. Eff es r -> IO r) -> IO a)
@@ -283,20 +290,40 @@ runEff m = unEff (evalEffect (IdE (IOE SeqUnlift)) m) =<< emptyEnv
283290instance IOE :> es => MonadIO (Eff es) where
284291 liftIO = unsafeEff_
285292
286−instance IOE :> es => MonadUnliftIO (Eff es) where
287− withRunInIO = unliftEff
293+instance IOE :> es => M.MonadUnliftIO (Eff es) where
294+ withRunInIO = withRunInIO
295+ where
296+ -- A trick to show name of the function in the call stack.
297+ withRunInIO
298+ :: (HasCallStack, IOE :> es)
299+ => ((forall r. Eff es r -> IO r) -> IO a)
300+ -> Eff es a
301+ withRunInIO f = unliftStrategy >>= \case
302+ SeqUnlift -> unsafeEff $ \es -> unsafeSeqUnliftEff es f
303+ ConcUnlift p b -> withUnliftStrategy SeqUnlift $ do
304+ unsafeEff $ \es -> unsafeConcUnliftEff es p b f
288305
289306-- | Instance included for compatibility with existing code, usage of 'liftIO'
290307-- is preferrable.
291−instance IOE :> es => MonadBase IO (Eff es) where
308+instance IOE :> es => M.MonadBase IO (Eff es) where
292309 liftBase = unsafeEff_
293310
294311-- | Instance included for compatibility with existing code, usage of
295312-- 'withRunInIO' is preferrable.
296−instance IOE :> es => MonadBaseControl IO (Eff es) where
313+instance IOE :> es => M.MonadBaseControl IO (Eff es) where
297314 type StM (Eff es) a = a
298− liftBaseWith = unliftEff
299315 restoreM = pure
316+ liftBaseWith = liftBaseWith
317+ where
318+ -- A trick to show name of the function in the call stack.
319+ liftBaseWith
320+ :: (HasCallStack, IOE :> es)
321+ => ((forall r. Eff es r -> IO r) -> IO a)
322+ -> Eff es a
323+ liftBaseWith f = unliftStrategy >>= \case
324+ SeqUnlift -> unsafeEff $ \es -> unsafeSeqUnliftEff es f
325+ ConcUnlift p b -> withUnliftStrategy SeqUnlift $ do
326+ unsafeEff $ \es -> unsafeConcUnliftEff es p b f
300327
301328----------------------------------------
302329-- Primitive
@@ -378,13 +405,6 @@ unliftStrategy = readerEffectM $ \(IdE (IOE unlift)) -> pure unlift
378405withUnliftStrategy :: IOE :> es => UnliftStrategy -> Eff es a -> Eff es a
379406withUnliftStrategy unlift = localEffect $ \_ -> IdE (IOE unlift)
380407
381−-- | Helper for 'MonadBaseControl' and 'MonadUnliftIO' instances.
382−unliftEff :: IOE :> es => ((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
383−unliftEff f = unliftStrategy >>= \case
384− SeqUnlift -> unsafeEff $ \es -> unsafeSeqUnliftEff es f
385− ConcUnlift p b -> withUnliftStrategy SeqUnlift $ do
386− unsafeEff $ \es -> unsafeConcUnliftEff es p b f
387−
388408----------------------------------------
389409-- Helpers
390410