Skip to content

Commit 645039f

Browse files
authored
Merge pull request #5 from natefaubion/hierarchy
Updated hierarchy
2 parents 4c0214f + 4f2a954 commit 645039f

File tree

4 files changed

+100
-71
lines changed

4 files changed

+100
-71
lines changed

bower.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@
1515
"package.json"
1616
],
1717
"dependencies": {
18-
"purescript-aff": "^3.0.0"
18+
"purescript-aff": "^4.0.0"
1919
}
2020
}

src/Control/Monad/Fork.purs

Lines changed: 0 additions & 23 deletions
This file was deleted.

src/Control/Monad/Fork/Canceler.purs

Lines changed: 0 additions & 36 deletions
This file was deleted.

src/Control/Monad/Fork/Class.purs

Lines changed: 99 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{-
2-
Copyright 2016 SlamData, Inc.
2+
Copyright 2017 SlamData, Inc.
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -16,19 +16,107 @@ limitations under the License.
1616

1717
module Control.Monad.Fork.Class where
1818

19-
import Prelude
19+
import Prelude hiding (join)
2020

2121
import Control.Monad.Aff as Aff
22-
import Control.Monad.Eff.Exception (Error)
23-
import Control.Monad.Reader.Trans (ReaderT(..))
22+
import Control.Monad.Error.Class (class MonadThrow, class MonadError)
23+
import Control.Monad.Reader.Trans (ReaderT(..), runReaderT)
2424
import Control.Monad.Trans.Class (lift)
2525

26-
class Monad m MonadFork e m | m e where
27-
fork a. m a m (e m Boolean)
26+
-- | Represents Monads which can be forked asynchronously.
27+
-- |
28+
-- | Laws:
29+
-- |
30+
-- | ```purescript
31+
-- | -- Unjoined suspension is a no-op
32+
-- | suspend a1 *> suspend a2 = suspend a2
33+
-- |
34+
-- | -- Suspend/join is identity
35+
-- | suspend >=> join = id
36+
-- |
37+
-- | -- Fork/join is identity
38+
-- | fork >=> join = id
39+
-- |
40+
-- | -- Join is idempotent
41+
-- | join t *> join t = join t
42+
-- | ```
43+
class (Monad m, Functor f) MonadFork f m | m f where
44+
suspend a. m a m (f a)
45+
fork a. m a m (f a)
46+
join a. f a m a
2847

29-
instance monadForkAffMonadFork Error (Aff.Aff eff) where
30-
fork = map Aff.cancel <<< Aff.forkAff
48+
instance monadForkAffMonadFork (Aff.Fiber eff) (Aff.Aff eff) where
49+
suspend = Aff.suspendAff
50+
fork = Aff.forkAff
51+
join = Aff.joinFiber
3152

32-
instance monadForkReaderTMonadFork e m MonadFork e (ReaderT r m) where
33-
fork (ReaderT ma) =
34-
ReaderT \r → map lift <$> fork (ma r)
53+
instance monadForkReaderTMonadFork f m MonadFork f (ReaderT r m) where
54+
suspend (ReaderT ma) = ReaderT (suspend <<< ma)
55+
fork (ReaderT ma) = ReaderT (fork <<< ma)
56+
join = lift <<< join
57+
58+
-- | Represents Monads which can be killed after being forked.
59+
-- |
60+
-- | Laws:
61+
-- |
62+
-- | ```purescript
63+
-- | -- Killed suspension is an exception
64+
-- | suspend a >>= \f -> kill e f *> join f = throwError e
65+
-- |
66+
-- | -- Suspend/kill is unit
67+
-- | suspend a >>= kill e = pure unit
68+
-- | ```
69+
class (MonadFork f m, MonadThrow e m) MonadKill e f m | m e f where
70+
kill a. e f a m Unit
71+
72+
instance monadKillAffMonadKill Aff.Error (Aff.Fiber eff) (Aff.Aff eff) where
73+
kill = Aff.killFiber
74+
75+
instance monadKillReaderTMonadKill e f m MonadKill e f (ReaderT r m) where
76+
kill e = lift <<< kill e
77+
78+
data BracketCondition e a
79+
= Completed a
80+
| Failed e
81+
| Killed e
82+
83+
-- | Represents Monads which support cleanup in the presence of async
84+
-- | exceptions.
85+
-- |
86+
-- | Laws:
87+
-- | ```purescript
88+
-- | bracket a k \_ -> pure r
89+
-- | = uninterruptible (a >>= k (Completed r))
90+
-- |
91+
-- | -- Release failed
92+
-- | bracket a k \_ -> throwError e
93+
-- | = uninterruptible (a >>= k (Failed e) *> throwError e)
94+
-- |
95+
-- | -- Release killed
96+
-- | fork (bracket a k \_ -> never) >>= \f -> kill e f *> void (try (join f))
97+
-- | = uninterruptible (a >>= k (Killed e))
98+
-- | ```
99+
class (MonadKill e f m, MonadError e m) MonadBracket e f m | m e f where
100+
bracket r a. m r (BracketCondition e a r m Unit) (r m a) m a
101+
uninterruptible a. m a m a
102+
never a. m a
103+
104+
instance monadBracketAffMonadBracket Aff.Error (Aff.Fiber eff) (Aff.Aff eff) where
105+
bracket acquire release run =
106+
Aff.generalBracket acquire
107+
{ completed: release <<< Completed
108+
, failed: release <<< Failed
109+
, killed: release <<< Killed
110+
}
111+
run
112+
uninterruptible = Aff.invincible
113+
never = Aff.never
114+
115+
instance monadBracketReaderTMonadBracket e f m MonadBracket e f (ReaderT r m) where
116+
bracket (ReaderT acquire) release run = ReaderT \r →
117+
bracket (acquire r)
118+
(\c a → runReaderT (release c a) r)
119+
(\a → runReaderT (run a) r)
120+
uninterruptible k = ReaderT \r ->
121+
uninterruptible (runReaderT k r)
122+
never = lift never

0 commit comments

Comments
 (0)