1{-# LANGUAGE UndecidableInstances #-}
7 -- * Asynchronous actions
12 -- ** Spawning with automatic 'cancel'ation
13 , withAsync, withAsyncBound, withAsyncOn, withAsyncWithUnmask
14 , withAsyncOnWithUnmask
16 -- ** Querying 'Async's
17 , wait, poll, waitCatch, A.asyncThreadId
18 , cancel, uninterruptibleCancel, cancelWith, A.AsyncCancelled(..)
20 -- ** #high-level-utilities# High-level utilities
22 , concurrently, concurrently_
23 , mapConcurrently, forConcurrently
24 , mapConcurrently_, forConcurrently_
25 , replicateConcurrently, replicateConcurrently_
29 -- ** Specialised operations
32 , A.waitSTM, A.pollSTM, A.waitCatchSTM
34 -- *** Waiting for multiple 'Async's
35 , waitAny, waitAnyCatch, waitAnyCancel, waitAnyCatchCancel
36 , waitEither, waitEitherCatch, waitEitherCancel, waitEitherCatchCancel
40 -- *** Waiting for multiple 'Async's in STM
41 , A.waitAnySTM, A.waitAnyCatchSTM
42 , A.waitEitherSTM, A.waitEitherCatchSTM
48 -- ** Spawning (low-level API)
49 , async, asyncBound, asyncOn, asyncWithUnmask, asyncOnWithUnmask
52 , link, linkOnly, link2, link2Only, A.ExceptionInLinkedThread(..)
55import Control.Applicative
56import Control.Concurrent (threadDelay)
57import Control.Concurrent.Async (Async)
58import Control.Exception (Exception, SomeException)
59import Control.Monad (forever, void)
60import Data.Foldable (fold)
61import qualified Control.Concurrent.Async as A
63import Effectful.Internal.Effect
64import Effectful.Internal.Env
65import Effectful.Internal.Monad
67-- | Run 'Eff' computations asynchronously using the @async@ library.
69-- /Note:/ thread local state changes in 'Eff' computations run asynchronously
70-- as 'Async' will not affect the parent thread.
71data AsyncE :: Effect where
74runAsyncE :: IOE :> es => Eff (AsyncE : es) a -> Eff es a
75runAsyncE = evalEffect (IdE AsyncE)
77-- | Generalized version of 'A.async'.
78async :: AsyncE :> es => Eff es a -> Eff es (Async a)
79async = liftAsync A.async
81-- | Generalized version of 'A.asyncBound'.
82asyncBound :: AsyncE :> es => Eff es a -> Eff es (Async a)
83asyncBound = liftAsync A.asyncBound
85-- | Generalized version of 'A.asyncOn'.
86asyncOn :: AsyncE :> es => Int -> Eff es a -> Eff es (Async a)
87asyncOn cpu = liftAsync (A.asyncOn cpu)
89-- | Generalized version of 'A.asyncWithUnmask'.
92 => ((forall b. Eff es b -> Eff es b) -> Eff es a)
94asyncWithUnmask = liftAsyncWithUnmask A.asyncWithUnmask
96-- | Generalized version of 'A.asyncOnWithUnmask'.
100 -> ((forall b. Eff es b -> Eff es b) -> Eff es a)
102asyncOnWithUnmask cpu = liftAsyncWithUnmask (A.asyncOnWithUnmask cpu)
104-- | Generalized version of 'A.withAsync'.
108 -> (Async a -> Eff es b)
110withAsync = liftWithAsync A.withAsync
112-- | Generalized version of 'A.withAsyncBound'.
116 -> (Async a -> Eff es b)
118withAsyncBound = liftWithAsync A.withAsyncBound
120-- | Generalized version of 'A.withAsyncOn'.
125 -> (Async a -> Eff es b)
127withAsyncOn cpu = liftWithAsync (A.withAsyncOn cpu)
129-- | Generalized version of 'A.withAsyncWithUnmask'.
132 => ((forall c. Eff es c -> Eff es c) -> Eff es a)
133 -> (Async a -> Eff es b)
135withAsyncWithUnmask = liftWithAsyncWithUnmask A.withAsyncWithUnmask
137-- | Generalized version of 'A.withAsyncOnWithUnmask'.
141 -> ((forall c. Eff es c -> Eff es c) -> Eff es a)
142 -> (Async a -> Eff es b)
144withAsyncOnWithUnmask cpu = liftWithAsyncWithUnmask (A.withAsyncOnWithUnmask cpu)
146-- | Generalized version of 'A.wait'.
147wait :: AsyncE :> es => Async a -> Eff es a
148wait = unsafeEff_ . A.wait
150-- | Generalized version of 'A.poll'.
154 -> Eff es (Maybe (Either SomeException a))
155poll = unsafeEff_ . A.poll
157-- | Generalized version of 'A.cancel'.
158cancel :: AsyncE :> es => Async a -> Eff es ()
159cancel = unsafeEff_ . A.cancel
161-- | Generalized version of 'A.cancelWith'.
162cancelWith :: (Exception e, AsyncE :> es) => Async a -> e -> Eff es ()
163cancelWith a = unsafeEff_ . A.cancelWith a
165-- | Generalized version of 'A.uninterruptibleCancel'.
166uninterruptibleCancel :: AsyncE :> es => Async a -> Eff es ()
167uninterruptibleCancel = unsafeEff_ . A.uninterruptibleCancel
169-- | Generalized version of 'A.waitCatch'.
173 -> Eff es (Either SomeException a)
174waitCatch = unsafeEff_ . A.waitCatch
176-- | Generalized version of 'A.waitAny'.
177waitAny :: AsyncE :> es => [Async a] -> Eff es (Async a, a)
178waitAny = unsafeEff_ . A.waitAny
180-- | Generalized version of 'A.waitAnyCatch'.
184 -> Eff es (Async a, Either SomeException a)
185waitAnyCatch = unsafeEff_ . A.waitAnyCatch
187-- | Generalized version of 'A.waitAnyCancel'.
188waitAnyCancel :: AsyncE :> es => [Async a] -> Eff es (Async a, a)
189waitAnyCancel = unsafeEff_ . A.waitAnyCancel
191-- | Generalized version of 'A.waitAnyCatchCancel'.
195 -> Eff es (Async a, Either SomeException a)
196waitAnyCatchCancel = unsafeEff_ . A.waitAnyCatchCancel
198-- | Generalized version of 'A.waitEither'.
203 -> Eff es (Either a b)
204waitEither a b = unsafeEff_ $ A.waitEither a b
206-- | Generalized version of 'A.waitEitherCatch'.
211 -> Eff es (Either (Either SomeException a) (Either SomeException b))
212waitEitherCatch a b = unsafeEff_ $ A.waitEitherCatch a b
214-- | Generalized version of 'A.waitEitherCancel'.
219 -> Eff es (Either a b)
220waitEitherCancel a b = unsafeEff_ $ A.waitEitherCancel a b
222-- | Generalized version of 'A.waitEitherCatchCancel'.
227 -> Eff es (Either (Either SomeException a) (Either SomeException b))
228waitEitherCatchCancel a b = unsafeEff_ $ A.waitEitherCatch a b
230-- | Generalized version of 'A.waitEither_'.
231waitEither_ :: AsyncE :> es => Async a -> Async b -> Eff es ()
232waitEither_ a b = unsafeEff_ $ A.waitEither_ a b
234-- | Generalized version of 'A.waitBoth'.
235waitBoth :: AsyncE :> es => Async a -> Async b -> Eff es (a, b)
236waitBoth a b = unsafeEff_ $ A.waitBoth a b
238-- | Generalized version of 'A.link'.
239link :: AsyncE :> es => Async a -> Eff es ()
240link = unsafeEff_ . A.link
242-- | Generalized version of 'A.linkOnly'.
243linkOnly :: AsyncE :> es => (SomeException -> Bool) -> Async a -> Eff es ()
244linkOnly f = unsafeEff_ . A.linkOnly f
246-- | Generalized version of 'A.link2'.
247link2 :: AsyncE :> es => Async a -> Async b -> Eff es ()
248link2 a b = unsafeEff_ $ A.link2 a b
250-- | Generalized version of 'A.link2Only'.
251link2Only :: AsyncE :> es => (SomeException -> Bool) -> Async a -> Async b -> Eff es ()
252link2Only f a b = unsafeEff_ $ A.link2Only f a b
254-- | Generalized version of 'A.race'.
255race :: AsyncE :> es => Eff es a -> Eff es b -> Eff es (Either a b)
256race ma mb = withAsync ma $ \a -> withAsync mb $ \b -> waitEither a b
258-- | Generalized version of 'A.race_'.
259race_ :: AsyncE :> es => Eff es a -> Eff es b -> Eff es ()
260race_ ma mb = withAsync ma $ \a -> withAsync mb $ \b -> waitEither_ a b
262-- | Generalized version of 'A.concurrently'.
263concurrently :: AsyncE :> es => Eff es a -> Eff es b -> Eff es (a, b)
264concurrently ma mb = withAsync ma $ \a -> withAsync mb $ \b -> waitBoth a b
266-- | Generalized version of 'A.concurrently_'.
267concurrently_ :: AsyncE :> es => Eff es a -> Eff es b -> Eff es ()
268concurrently_ ma mb = void $ concurrently ma mb
270-- | Generalized version of 'A.mapConcurrently'.
272 :: (Traversable f, AsyncE :> es)
276mapConcurrently f = runConcurrently . traverse (Concurrently . f)
278-- | Generalized version of 'A.mapConcurrently_'.
280 :: (Foldable f, AsyncE :> es)
284mapConcurrently_ f = runConcurrently . foldMap (Concurrently . void . f)
286-- | Generalized version of 'A.forConcurrently'.
288 :: (Traversable f, AsyncE :> es)
292forConcurrently = flip mapConcurrently
294-- | Generalized version of 'A.forConcurrently_'.
296 :: (Foldable f, AsyncE :> es)
300forConcurrently_ = flip mapConcurrently_
302-- | Generalized version of 'A.replicateConcurrently'.
303replicateConcurrently :: AsyncE :> es => Int -> Eff es a -> Eff es [a]
304replicateConcurrently n =
305 runConcurrently . sequenceA . replicate n . Concurrently
307-- | Generalized version of 'A.replicateConcurrently_'.
308replicateConcurrently_ :: AsyncE :> es => Int -> Eff es a -> Eff es ()
309replicateConcurrently_ n =
310 runConcurrently . fold . replicate n . Concurrently . void
312----------------------------------------
314-- | Generalized version of 'A.Concurrently'.
315newtype Concurrently es a = Concurrently { runConcurrently :: Eff es a }
317instance Functor (Concurrently es) where
318 fmap f (Concurrently a) = Concurrently (fmap f a)
320instance AsyncE :> es => Applicative (Concurrently es) where
321 pure = Concurrently . pure
322 Concurrently fs <*> Concurrently as =
323 Concurrently ((\(f, a) -> f a) <$> concurrently fs as)
325instance AsyncE :> es => Alternative (Concurrently es) where
326 empty = Concurrently . unsafeEff_ . forever $ threadDelay maxBound
327 Concurrently as <|> Concurrently bs =
328 Concurrently (either id id <$> race as bs)
330instance (AsyncE :> es, Semigroup a) => Semigroup (Concurrently es a) where
333instance (AsyncE :> es, Monoid a) => Monoid (Concurrently es a) where
336----------------------------------------
340 :: (IO a -> IO (Async a))
343liftAsync fork action = unsafeEff $ \es0 -> do
345 fork $ unEff action es
348 :: (((forall b. IO b -> IO b) -> IO a) -> IO (Async a))
349 -> ((forall b. Eff es b -> Eff es b) -> Eff es a)
351liftAsyncWithUnmask fork action = unsafeEff $ \es0 -> do
353 fork $ \unmask -> unEff (action $ \m -> unsafeEff $ unmask . unEff m) es
356 :: (IO a -> (Async a -> IO b) -> IO b)
358 -> (Async a -> Eff es b)
360liftWithAsync withA action k = unsafeEff $ \es0 -> do
362 withA (unEff action es)
363 (\a -> unEff (k a) es0)
365liftWithAsyncWithUnmask
366 :: (((forall c. IO c -> IO c) -> IO a) -> (Async a -> IO b) -> IO b)
367 -> ((forall c. Eff es c -> Eff es c) -> Eff es a)
368 -> (Async a -> Eff es b)
370liftWithAsyncWithUnmask withA action k = unsafeEff $ \es0 -> do
372 withA (\unmask -> unEff (action $ \m -> unsafeEff $ unmask . unEff m) es)
373 (\a -> unEff (k a) es0)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list