1
- {-# LANGUAGE DefaultSignatures #-}
2
- {-# LANGUAGE FlexibleContexts #-}
3
- {-# LANGUAGE MultiParamTypeClasses #-}
4
- {-# LANGUAGE QuantifiedConstraints #-}
5
- {-# LANGUAGE ScopedTypeVariables #-}
6
- {-# LANGUAGE RankNTypes #-}
7
- {-# LANGUAGE TypeApplications #-}
8
- {-# LANGUAGE TypeFamilies #-}
1
+ {-# LANGUAGE DefaultSignatures #-}
2
+ {-# LANGUAGE FlexibleContexts #-}
3
+ {-# LANGUAGE MultiParamTypeClasses #-}
4
+ {-# LANGUAGE QuantifiedConstraints #-}
5
+ {-# LANGUAGE ScopedTypeVariables #-}
6
+ {-# LANGUAGE RankNTypes #-}
7
+ {-# LANGUAGE TypeApplications #-}
8
+ {-# LANGUAGE TypeFamilies #-}
9
+ {-# LANGUAGE TypeFamilyDependencies #-}
9
10
10
11
module Control.Monad.Class.MonadAsync
11
12
( MonadAsync (.. )
12
- , MonadAsyncSTM (.. )
13
13
, AsyncCancelled (.. )
14
14
, ExceptionInLinkedThread (.. )
15
15
, link
@@ -30,40 +30,63 @@ import Control.Monad.Class.MonadFork
30
30
import Control.Monad.Class.MonadSTM
31
31
import Control.Monad.Class.MonadTimer
32
32
import Control.Monad.Class.MonadThrow
33
+ import Control.Monad (forever )
33
34
34
35
import Control.Concurrent.Async (AsyncCancelled (.. ))
35
36
import qualified Control.Concurrent.Async as Async
36
37
import qualified Control.Exception as E
37
- import Control.Monad.Reader
38
- import qualified Control.Monad.STM as STM
39
38
40
39
import Data.Foldable (fold )
40
+ import Data.Functor (void )
41
41
import Data.Kind (Type )
42
- import Data.Proxy
43
42
44
- class (Functor async , MonadSTMTx stm ) => MonadAsyncSTM async stm where
45
- {-# MINIMAL waitCatchSTM, pollSTM #-}
43
+ class ( MonadSTM m
44
+ , MonadThread m
45
+ ) => MonadAsync m where
46
46
47
- waitSTM :: async a -> stm a
48
- pollSTM :: async a -> stm (Maybe (Either SomeException a ))
49
- waitCatchSTM :: async a -> stm (Either SomeException a )
47
+ {-# MINIMAL async, asyncThreadId, cancel, cancelWith, asyncWithUnmask,
48
+ waitCatchSTM, pollSTM #-}
50
49
51
- default waitSTM :: MonadThrow stm => async a -> stm a
50
+ -- | An asynchronous action
51
+ type Async m = (async :: Type -> Type ) | async -> m
52
+
53
+ async :: m a -> m (Async m a )
54
+ asyncThreadId :: Async m a -> ThreadId m
55
+ withAsync :: m a -> (Async m a -> m b ) -> m b
56
+
57
+ waitSTM :: Async m a -> STM m a
58
+ pollSTM :: Async m a -> STM m (Maybe (Either SomeException a ))
59
+ waitCatchSTM :: Async m a -> STM m (Either SomeException a )
60
+
61
+ default waitSTM :: MonadThrow (STM m ) => Async m a -> STM m a
52
62
waitSTM action = waitCatchSTM action >>= either throwSTM return
53
63
54
- waitAnySTM :: [async a ] -> stm ( async a , a )
55
- waitAnyCatchSTM :: [async a ] -> stm ( async a , Either SomeException a )
56
- waitEitherSTM :: async a -> async b -> stm (Either a b )
57
- waitEitherSTM_ :: async a -> async b -> stm ()
58
- waitEitherCatchSTM :: async a -> async b
59
- -> stm (Either (Either SomeException a )
64
+ waitAnySTM :: [Async m a ] -> STM m ( Async m a , a )
65
+ waitAnyCatchSTM :: [Async m a ] -> STM m ( Async m a , Either SomeException a )
66
+ waitEitherSTM :: Async m a -> Async m b -> STM m (Either a b )
67
+ waitEitherSTM_ :: Async m a -> Async m b -> STM m ()
68
+ waitEitherCatchSTM :: Async m a -> Async m b
69
+ -> STM m (Either (Either SomeException a )
60
70
(Either SomeException b ))
61
- waitBothSTM :: async a -> async b -> stm (a , b )
71
+ waitBothSTM :: Async m a -> Async m b -> STM m (a , b )
72
+
73
+ wait :: Async m a -> m a
74
+ poll :: Async m a -> m (Maybe (Either SomeException a ))
75
+ waitCatch :: Async m a -> m (Either SomeException a )
76
+ cancel :: Async m a -> m ()
77
+ cancelWith :: Exception e => Async m a -> e -> m ()
78
+ uninterruptibleCancel :: Async m a -> m ()
62
79
63
- default waitAnySTM :: MonadThrow stm => [async a ] -> stm (async a , a )
64
- default waitEitherSTM :: MonadThrow stm => async a -> async b -> stm (Either a b )
65
- default waitEitherSTM_ :: MonadThrow stm => async a -> async b -> stm ()
66
- default waitBothSTM :: MonadThrow stm => async a -> async b -> stm (a , b )
80
+ waitAny :: [Async m a ] -> m (Async m a , a )
81
+ waitAnyCatch :: [Async m a ] -> m (Async m a , Either SomeException a )
82
+ waitAnyCancel :: [Async m a ] -> m (Async m a , a )
83
+ waitAnyCatchCancel :: [Async m a ] -> m (Async m a , Either SomeException a )
84
+ waitEither :: Async m a -> Async m b -> m (Either a b )
85
+
86
+ default waitAnySTM :: MonadThrow (STM m ) => [Async m a ] -> STM m (Async m a , a )
87
+ default waitEitherSTM :: MonadThrow (STM m ) => Async m a -> Async m b -> STM m (Either a b )
88
+ default waitEitherSTM_ :: MonadThrow (STM m ) => Async m a -> Async m b -> STM m ()
89
+ default waitBothSTM :: MonadThrow (STM m ) => Async m a -> Async m b -> STM m (a , b )
67
90
68
91
waitAnySTM as =
69
92
foldr orElse retry $
@@ -95,33 +118,6 @@ class (Functor async, MonadSTMTx stm) => MonadAsyncSTM async stm where
95
118
b <- waitSTM right
96
119
return (a,b)
97
120
98
- class ( MonadSTM m
99
- , MonadThread m
100
- , MonadAsyncSTM (Async m ) (STM m )
101
- ) => MonadAsync m where
102
-
103
- {-# MINIMAL async, asyncThreadId, cancel, cancelWith, asyncWithUnmask #-}
104
-
105
- -- | An asynchronous action
106
- type Async m :: Type -> Type
107
-
108
- async :: m a -> m (Async m a )
109
- asyncThreadId :: Proxy m -> Async m a -> ThreadId m
110
- withAsync :: m a -> (Async m a -> m b ) -> m b
111
-
112
- wait :: Async m a -> m a
113
- poll :: Async m a -> m (Maybe (Either SomeException a ))
114
- waitCatch :: Async m a -> m (Either SomeException a )
115
- cancel :: Async m a -> m ()
116
- cancelWith :: Exception e => Async m a -> e -> m ()
117
- uninterruptibleCancel :: Async m a -> m ()
118
-
119
- waitAny :: [Async m a ] -> m (Async m a , a )
120
- waitAnyCatch :: [Async m a ] -> m (Async m a , Either SomeException a )
121
- waitAnyCancel :: [Async m a ] -> m (Async m a , a )
122
- waitAnyCatchCancel :: [Async m a ] -> m (Async m a , Either SomeException a )
123
- waitEither :: Async m a -> Async m b -> m (Either a b )
124
-
125
121
-- | Note, IO-based implementations should override the default
126
122
-- implementation. See the @async@ package implementation and comments.
127
123
-- <http://hackage.haskell.org/package/async-2.2.1/docs/src/Control.Concurrent.Async.html#waitEitherCatch>
@@ -258,25 +254,25 @@ replicateConcurrently_ cnt = runConcurrently . fold . replicate cnt . Concurrent
258
254
-- Instance for IO uses the existing async library implementations
259
255
--
260
256
261
- instance MonadAsyncSTM Async. Async STM. STM where
262
- waitSTM = Async. waitSTM
263
- pollSTM = Async. pollSTM
264
- waitCatchSTM = Async. waitCatchSTM
265
- waitAnySTM = Async. waitAnySTM
266
- waitAnyCatchSTM = Async. waitAnyCatchSTM
267
- waitEitherSTM = Async. waitEitherSTM
268
- waitEitherSTM_ = Async. waitEitherSTM_
269
- waitEitherCatchSTM = Async. waitEitherCatchSTM
270
- waitBothSTM = Async. waitBothSTM
271
-
272
257
instance MonadAsync IO where
273
258
274
259
type Async IO = Async. Async
275
260
276
261
async = Async. async
277
- asyncThreadId = \ _proxy -> Async. asyncThreadId
262
+ asyncThreadId = Async. asyncThreadId
278
263
withAsync = Async. withAsync
279
264
265
+ waitSTM = Async. waitSTM
266
+ pollSTM = Async. pollSTM
267
+ waitCatchSTM = Async. waitCatchSTM
268
+
269
+ waitAnySTM = Async. waitAnySTM
270
+ waitAnyCatchSTM = Async. waitAnyCatchSTM
271
+ waitEitherSTM = Async. waitEitherSTM
272
+ waitEitherSTM_ = Async. waitEitherSTM_
273
+ waitEitherCatchSTM = Async. waitEitherCatchSTM
274
+ waitBothSTM = Async. waitBothSTM
275
+
280
276
wait = Async. wait
281
277
poll = Async. poll
282
278
waitCatch = Async. waitCatch
@@ -302,47 +298,6 @@ instance MonadAsync IO where
302
298
303
299
asyncWithUnmask = Async. asyncWithUnmask
304
300
305
- --
306
- -- Lift to ReaderT
307
- --
308
-
309
- (.:) :: (c -> d ) -> (a -> b -> c ) -> (a -> b -> d )
310
- (f .: g) x y = f (g x y)
311
-
312
- instance MonadAsync m => MonadAsync (ReaderT r m ) where
313
- type Async (ReaderT r m ) = Async m
314
-
315
- asyncThreadId _ = asyncThreadId (Proxy @ m )
316
-
317
- async (ReaderT ma) = ReaderT $ \ r -> async (ma r)
318
- withAsync (ReaderT ma) f = ReaderT $ \ r -> withAsync (ma r) $ \ a -> runReaderT (f a) r
319
- asyncWithUnmask f = ReaderT $ \ r ->
320
- asyncWithUnmask $ \ unmask ->
321
- runReaderT (f (liftF unmask)) r
322
- where
323
- liftF :: (m a -> m a ) -> ReaderT r m a -> ReaderT r m a
324
- liftF g (ReaderT r) = ReaderT (g . r)
325
-
326
- race (ReaderT ma) (ReaderT mb) = ReaderT $ \ r -> race (ma r) (mb r)
327
- race_ (ReaderT ma) (ReaderT mb) = ReaderT $ \ r -> race_ (ma r) (mb r)
328
- concurrently (ReaderT ma) (ReaderT mb) = ReaderT $ \ r -> concurrently (ma r) (mb r)
329
-
330
- wait = lift . wait
331
- poll = lift . poll
332
- waitCatch = lift . waitCatch
333
- cancel = lift . cancel
334
- uninterruptibleCancel = lift . uninterruptibleCancel
335
- cancelWith = lift .: cancelWith
336
- waitAny = lift . waitAny
337
- waitAnyCatch = lift . waitAnyCatch
338
- waitAnyCancel = lift . waitAnyCancel
339
- waitAnyCatchCancel = lift . waitAnyCatchCancel
340
- waitEither = lift .: waitEither
341
- waitEitherCatch = lift .: waitEitherCatch
342
- waitEitherCancel = lift .: waitEitherCancel
343
- waitEitherCatchCancel = lift .: waitEitherCatchCancel
344
- waitEither_ = lift .: waitEither_
345
- waitBoth = lift .: waitBoth
346
301
347
302
--
348
303
-- Linking
@@ -401,7 +356,7 @@ linkToOnly tid shouldThrow a = do
401
356
_otherwise -> return ()
402
357
where
403
358
linkedThreadId :: ThreadId m
404
- linkedThreadId = asyncThreadId ( Proxy @ m ) a
359
+ linkedThreadId = asyncThreadId a
405
360
406
361
exceptionInLinkedThread :: SomeException -> ExceptionInLinkedThread
407
362
exceptionInLinkedThread =
0 commit comments