@@ -21,7 +21,9 @@ module Effectful.Interpreter
22 -- *** 'IO'
22 -- *** 'IO'
23 , localSeqUnliftIO
23 , localSeqUnliftIO
24+ , localSeqLiftUnliftIO
24 , localUnliftIO
25 , localUnliftIO
27import Control.Exception
29import Control.Exception
@@ -127,7 +129,8 @@ reinterpretM runHandlerEs interpreter m = unsafeEff $ \es -> do
127----------------------------------------
129----------------------------------------
128-- Unlifting
130-- Unlifting
130−-- | Create a local unlifting function with the 'SeqUnlift' strategy.
132+-- | Create a local unlifting function with the 'SeqUnlift' strategy. For the
133+-- general version see 'localUnlift'.
131localSeqUnlift
134localSeqUnlift
132 :: LocalEnv localEs
135 :: LocalEnv localEs
133 -- ^ Local environment from the effect handler.
136 -- ^ Local environment from the effect handler.
@@ -137,7 +140,8 @@ localSeqUnlift
137localSeqUnlift (LocalEnv les) f = unsafeEff $ \es -> do
140localSeqUnlift (LocalEnv les) f = unsafeEff $ \es -> do
138 unEff (seqUnliftEff $ \k -> unEff (f $ unsafeEff_ . k) es) les
141 unEff (seqUnliftEff $ \k -> unEff (f $ unsafeEff_ . k) es) les
140−-- | Create a local unlifting function with the 'SeqUnlift' strategy.
143+-- | Create a local unlifting function with the 'SeqUnlift' strategy. For the
144+-- general version see 'localUnliftIO'.
141localSeqUnliftIO
145localSeqUnliftIO
142 :: IOE :> es
146 :: IOE :> es
143 => LocalEnv localEs
147 => LocalEnv localEs
@@ -147,6 +151,21 @@ localSeqUnliftIO
147 -> Eff es a
151 -> Eff es a
148localSeqUnliftIO (LocalEnv les) f = unsafeEff_ $ unEff (seqUnliftEff f) les
152localSeqUnliftIO (LocalEnv les) f = unsafeEff_ $ unEff (seqUnliftEff f) les
154+-- | Create a local lifting and unlifting function with the 'SeqUnlift'
155+-- strategy. More the general version see 'localLiftUnliftIO'.
157+-- /Note:/ the strategy applies only to the unlifting function, lifting function
158+-- doesn't have any restrictions.
162+ -- ^ Local environment from the effect handler.
163+ -> ((forall r. IO r -> Eff localEs r) -> (forall r. Eff localEs r -> IO r) -> IO a)
164+ -- ^ Continuation with the lifting and unlifting function.
166+localSeqLiftUnliftIO (LocalEnv les) f = unsafeEff_ $ do
167+ unEff (seqUnliftEff $ f unsafeEff_) les
150-- | Create a local unlifting function with the given strategy.
169-- | Create a local unlifting function with the given strategy.
151localUnlift
170localUnlift
152 :: LocalEnv localEs
171 :: LocalEnv localEs
@@ -171,3 +190,38 @@ localUnliftIO
171localUnliftIO (LocalEnv les) unlift f = unsafeEff_ $ case unlift of
190localUnliftIO (LocalEnv les) unlift f = unsafeEff_ $ case unlift of
172 SeqUnlift -> unEff (seqUnliftEff f) les
191 SeqUnlift -> unEff (seqUnliftEff f) les
173 ConcUnlift p b -> unEff (concUnliftEff p b f) les
192 ConcUnlift p b -> unEff (concUnliftEff p b f) les
194+-- | Create a local lifting and unlifting function with the given strategy.
196+-- /Note:/ the strategy applies only to the unlifting function, lifting function
197+-- doesn't have any restrictions.
199+-- Necessary for lifting 'Control.Concurrent.forkIOWithUnmask'-like operations:
202+-- data Fork :: Effect where
203+-- ForkWithUnmask :: ((forall a. m a -> m a) -> m ()) -> Fork m ThreadId
207+-- runFork :: IOE :> es => Eff (Fork : es) a -> Eff es a
208+-- runFork = interpretM $ \env (ForkWithUnmask m) -> do
209+-- localLiftUnliftIO env (ConcUnlift Persistent $ Limited 1) $ \lift unlift -> do
210+-- forkIOWithUnmask $ \unmask -> unlift $ m $ lift . unmask . unlift
216+ -- ^ Local environment from the effect handler.
218+ -> ((forall r. IO r -> Eff localEs r) -> (forall r. Eff localEs r -> IO r) -> IO a)
219+ -- ^ Continuation with the lifting and unlifting function.
221+localLiftUnliftIO (LocalEnv les) unlift f = unsafeEff_ $ case unlift of
222+ SeqUnlift -> unEff (seqUnliftEff $ f unsafeEff_) les
223+ ConcUnlift p b -> unEff (concUnliftEff p b $ f unsafeEff_) les
226+-- >>> import Control.Concurrent
227+-- >>> import Effectful