@@ -19,210 +19,206 @@ module Control.Monad.Aff
1919 )
2020 where
2121
22- import Prelude
23-
24- import Control.Alt (Alt )
25- import Control.Alternative (Alternative )
26- import Control.Monad.Cont.Class (MonadCont )
27- import Control.Monad.Eff (Eff ())
28- import Control.Monad.Eff.Class (MonadEff , liftEff )
29- import Control.Monad.Eff.Exception (Error (), EXCEPTION (), catchException , throwException , error )
30- import Control.Monad.Eff.Unsafe (unsafeInterleaveEff )
31- import Control.Monad.Error.Class (MonadError , throwError )
32- import Control.Monad.Rec.Class (MonadRec , tailRecM )
33- import Control.MonadPlus (MonadPlus )
34- import Control.Plus (Plus )
35-
36- import Data.Either (Either (..), either )
37- import Data.Function (Fn2 (), Fn3 (), runFn2 , runFn3 )
38- import Data.Monoid (Monoid , mempty )
39-
40- -- | An asynchronous computation with effects `e`. The computation either
41- -- | errors or produces a value of type `a`.
42- -- |
43- -- | This is moral equivalent of `ErrorT (ContT Unit (Eff e)) a`.
44- foreign import data Aff :: # ! -> * -> *
45-
46- -- | A pure asynchronous computation, having no effects other than
47- -- | asynchronous computation.
48- type PureAff a = forall e. Aff e a
49-
50- -- | A canceler is asynchronous function that can be used to attempt the
51- -- | cancelation of a computation. Returns a boolean flag indicating whether
52- -- | or not the cancellation was successful. Many computations may be composite,
53- -- | in such cases the flag indicates whether any part of the computation was
54- -- | successfully canceled. The flag should not be used for communication.
55- newtype Canceler e = Canceler (Error -> Aff e Boolean )
56-
57- -- | Unwraps the canceler function from the newtype that wraps it.
58- cancel :: forall e. Canceler e -> Error -> Aff e Boolean
59- cancel (Canceler f ) = f
60-
61- -- | This function allows you to attach a custom canceler to an asynchronous
62- -- | computation. If the computation is canceled, then the custom canceler
63- -- | will be run along side the computation's own canceler.
64- cancelWith :: forall e a. Aff e a -> Canceler e -> Aff e a
65- cancelWith aff c = runFn3 _cancelWith nonCanceler aff c
66-
67- -- | Converts the asynchronous computation into a synchronous one. All values
68- -- | are ignored, and if the computation produces an error, it is thrown.
69- -- |
70- -- | Catching exceptions by using `catchException` with the resulting Eff
71- -- | computation is not recommended, as exceptions may end up being thrown
72- -- | asynchronously, in which case they cannot be caught.
73- -- |
74- -- | If you do need to handle exceptions, you can use `runAff` instead, or
75- -- | you can handle the exception within the Aff computation, using
76- -- | `catchError` (or any of the other mechanisms).
77- launchAff :: forall e a. Aff e a -> Eff (err :: EXCEPTION | e ) Unit
78- launchAff = runAff throwException (const (pure unit)) <<< liftEx
79- where
80- liftEx :: forall e a. Aff e a -> Aff (err :: EXCEPTION | e ) a
81- liftEx = _unsafeInterleaveAff
82-
83- -- | Runs the asynchronous computation. You must supply an error callback and a
84- -- | success callback.
85- runAff :: forall e a. (Error -> Eff e Unit ) -> (a -> Eff e Unit ) -> Aff e a -> Eff e Unit
86- runAff ex f aff = runFn3 _runAff ex f aff
87-
88- -- | Creates an asynchronous effect from a function that accepts error and
89- -- | success callbacks. This function can be used for asynchronous computations
90- -- | that cannot be canceled.
91- makeAff :: forall e a. ((Error -> Eff e Unit) -> (a -> Eff e Unit) -> Eff e Unit ) -> Aff e a
92- makeAff h = makeAff' (\e a -> const nonCanceler <$> h e a )
93-
94- -- | Creates an asynchronous effect from a function that accepts error and
95- -- | success callbacks, and returns a canceler for the computation. This
96- -- | function can be used for asynchronous computations that can be canceled.
97- makeAff' :: forall e a. ((Error -> Eff e Unit) -> (a -> Eff e Unit) -> Eff e (Canceler e)) -> Aff e a
98- makeAff' h = _makeAff h
22+ import Prelude
23+
24+ import Control.Alt (Alt )
25+ import Control.Alternative (Alternative )
26+ import Control.Monad.Cont.Class (MonadCont )
27+ import Control.Monad.Eff (Eff ())
28+ import Control.Monad.Eff.Class (MonadEff )
29+ import Control.Monad.Eff.Exception (Error (), EXCEPTION (), throwException , error )
30+ import Control.Monad.Error.Class (MonadError , throwError )
31+ import Control.Monad.Rec.Class (MonadRec , tailRecM )
32+ import Control.MonadPlus (MonadPlus )
33+ import Control.Plus (Plus )
34+
35+ import Data.Either (Either (..), either )
36+ import Data.Function (Fn2 (), Fn3 (), runFn2 , runFn3 )
37+ import Data.Monoid (Monoid , mempty )
38+
39+ -- | An asynchronous computation with effects `e`. The computation either
40+ -- | errors or produces a value of type `a`.
41+ -- |
42+ -- | This is moral equivalent of `ErrorT (ContT Unit (Eff e)) a`.
43+ foreign import data Aff :: # ! -> * -> *
44+
45+ -- | A pure asynchronous computation, having no effects other than
46+ -- | asynchronous computation.
47+ type PureAff a = forall e . Aff e a
48+
49+ -- | A canceler is asynchronous function that can be used to attempt the
50+ -- | cancelation of a computation. Returns a boolean flag indicating whether
51+ -- | or not the cancellation was successful. Many computations may be composite,
52+ -- | in such cases the flag indicates whether any part of the computation was
53+ -- | successfully canceled. The flag should not be used for communication.
54+ newtype Canceler e = Canceler (Error -> Aff e Boolean )
55+
56+ -- | Unwraps the canceler function from the newtype that wraps it.
57+ cancel :: forall e . Canceler e -> Error -> Aff e Boolean
58+ cancel (Canceler f) = f
59+
60+ -- | This function allows you to attach a custom canceler to an asynchronous
61+ -- | computation. If the computation is canceled, then the custom canceler
62+ -- | will be run along side the computation's own canceler.
63+ cancelWith :: forall e a . Aff e a -> Canceler e -> Aff e a
64+ cancelWith aff c = runFn3 _cancelWith nonCanceler aff c
65+
66+ -- | Converts the asynchronous computation into a synchronous one. All values
67+ -- | are ignored, and if the computation produces an error, it is thrown.
68+ -- |
69+ -- | Catching exceptions by using `catchException` with the resulting Eff
70+ -- | computation is not recommended, as exceptions may end up being thrown
71+ -- | asynchronously, in which case they cannot be caught.
72+ -- |
73+ -- | If you do need to handle exceptions, you can use `runAff` instead, or
74+ -- | you can handle the exception within the Aff computation, using
75+ -- | `catchError` (or any of the other mechanisms).
76+ launchAff :: forall e a . Aff e a -> Eff (err :: EXCEPTION | e ) Unit
77+ launchAff = runAff throwException (const (pure unit)) <<< liftEx
78+ where
79+ liftEx :: Aff e a -> Aff (err :: EXCEPTION | e ) a
80+ liftEx = _unsafeInterleaveAff
9981
100- -- | Runs the asynchronous computation off the current execution context.
101- later :: forall e a. Aff e a -> Aff e a
102- later = later' 0
82+ -- | Runs the asynchronous computation. You must supply an error callback and a
83+ -- | success callback.
84+ runAff :: forall e a . (Error -> Eff e Unit ) -> (a -> Eff e Unit ) -> Aff e a -> Eff e Unit
85+ runAff ex f aff = runFn3 _runAff ex f aff
10386
104- -- | Runs the specified asynchronous computation later, by the specified
105- -- | number of milliseconds.
106- later' :: forall e a. Int -> Aff e a -> Aff e a
107- later' n aff = runFn3 _setTimeout nonCanceler n aff
87+ -- | Creates an asynchronous effect from a function that accepts error and
88+ -- | success callbacks. This function can be used for asynchronous computations
89+ -- | that cannot be canceled.
90+ makeAff :: forall e a . ((Error -> Eff e Unit ) -> (a -> Eff e Unit ) -> Eff e Unit ) -> Aff e a
91+ makeAff h = makeAff' (\e a -> const nonCanceler <$> h e a)
10892
109- -- | Compute `aff1`, followed by `aff2` regardless of whether `aff1` terminated successfully.
110- finally :: forall e a b. Aff e a -> Aff e b -> Aff e a
111- finally aff1 aff2 = do
112- x <- attempt aff1
113- aff2
114- either throwError pure x
93+ -- | Creates an asynchronous effect from a function that accepts error and
94+ -- | success callbacks, and returns a canceler for the computation. This
95+ -- | function can be used for asynchronous computations that can be canceled.
96+ makeAff' :: forall e a . ((Error -> Eff e Unit ) -> (a -> Eff e Unit ) -> Eff e (Canceler e )) -> Aff e a
97+ makeAff' h = _makeAff h
11598
116- -- | Forks the specified asynchronous computation so subsequent computations
117- -- | will not block on the result of the computation.
118- -- |
119- -- | Returns a canceler that can be used to attempt cancellation of the
120- -- | forked computation.
121- forkAff :: forall e a. Aff e a -> Aff e (Canceler e )
122- forkAff aff = runFn2 _forkAff nonCanceler aff
99+ -- | Runs the asynchronous computation off the current execution context.
100+ later :: forall e a . Aff e a -> Aff e a
101+ later = later' 0
123102
124- -- | Promotes any error to the value level of the asynchronous monad.
125- attempt :: forall e a. Aff e a -> Aff e (Either Error a )
126- attempt aff = runFn3 _attempt Left Right aff
103+ -- | Runs the specified asynchronous computation later, by the specified
104+ -- | number of milliseconds.
105+ later' :: forall e a . Int -> Aff e a -> Aff e a
106+ later' n aff = runFn3 _setTimeout nonCanceler n aff
127107
128- -- | Ignores any errors.
129- apathize :: forall e a. Aff e a -> Aff e Unit
130- apathize a = const unit <$> attempt a
108+ -- | Compute `aff1`, followed by `aff2` regardless of whether `aff1` terminated successfully.
109+ finally :: forall e a b . Aff e a -> Aff e b -> Aff e a
110+ finally aff1 aff2 = do
111+ x <- attempt aff1
112+ aff2
113+ either throwError pure x
131114
132- -- | Lifts a synchronous computation and makes explicit any failure from exceptions.
133- liftEff' :: forall e a. Eff (err :: EXCEPTION | e ) a -> Aff e (Either Error a )
134- liftEff' eff = attempt (_unsafeInterleaveAff (runFn2 _liftEff nonCanceler eff))
115+ -- | Forks the specified asynchronous computation so subsequent computations
116+ -- | will not block on the result of the computation.
117+ -- |
118+ -- | Returns a canceler that can be used to attempt cancellation of the
119+ -- | forked computation.
120+ forkAff :: forall e a . Aff e a -> Aff e (Canceler e )
121+ forkAff aff = runFn2 _forkAff nonCanceler aff
135122
136- -- | A constant canceller that always returns false .
137- non Canceler :: forall e. Canceler e
138- non Canceler = Canceler ( const (pure false))
123+ -- | Promotes any error to the value level of the asynchronous monad .
124+ attempt :: forall e a . Aff e a -> Aff e ( Either Error a )
125+ attempt aff = runFn3 _attempt Left Right aff
139126
140- -- | A constant canceller that always returns true .
141- always Canceler :: forall e. Canceler e
142- always Canceler = Canceler ( const (pure true))
127+ -- | Ignores any errors .
128+ apathize :: forall e a . Aff e a -> Aff e Unit
129+ apathize a = const unit <$> attempt a
143130
144- instance semigroupAff :: (Semigroup a ) => Semigroup (Aff e a ) where
145- append a b = (<>) <$> a <*> b
131+ -- | Lifts a synchronous computation and makes explicit any failure from exceptions.
132+ liftEff' :: forall e a . Eff (err :: EXCEPTION | e ) a -> Aff e (Either Error a )
133+ liftEff' eff = attempt (_unsafeInterleaveAff (runFn2 _liftEff nonCanceler eff))
146134
147- instance monoidAff :: (Monoid a ) => Monoid (Aff e a ) where
148- mempty = pure mempty
135+ -- | A constant canceller that always returns false.
136+ nonCanceler :: forall e . Canceler e
137+ nonCanceler = Canceler (const (pure false ))
149138
150- instance functorAff :: Functor (Aff e ) where
151- map f fa = runFn2 _fmap f fa
139+ -- | A constant canceller that always returns true.
140+ alwaysCanceler :: forall e . Canceler e
141+ alwaysCanceler = Canceler (const (pure true ))
152142
153- instance apply Aff :: Apply (Aff e ) where
154- apply ff fa = run Fn3 _bind always Canceler ff (\ f -> f <$> fa )
143+ instance semigroupAff :: ( Semigroup a ) => Semigroup (Aff e a ) where
144+ append a b = (<>) <$> a <*> b
155145
156- instance applicative Aff :: Applicative (Aff e ) where
157- pure v = run Fn2 _pure non Canceler v
146+ instance monoidAff :: ( Monoid a ) => Monoid (Aff e a ) where
147+ mempty = pure mempty
158148
159- instance bind Aff :: Bind (Aff e ) where
160- bind fa f = run Fn3 _bind always Canceler fa f
149+ instance functorAff :: Functor (Aff e ) where
150+ map f fa = runFn2 _fmap f fa
161151
162- instance monadAff :: Monad (Aff e )
152+ instance applyAff :: Apply (Aff e ) where
153+ apply ff fa = runFn3 _bind alwaysCanceler ff (\f -> f <$> fa)
163154
164- instance monad EffAff :: MonadEff e (Aff e ) where
165- lift Eff eff = runFn2 _lift Eff nonCanceler eff
155+ instance applicativeAff :: Applicative (Aff e ) where
156+ pure v = runFn2 _pure nonCanceler v
166157
167- -- | Allows users to catch and throw errors on the error channel of the
168- -- | asynchronous computation. See documentation in `purescript-transformers`.
169- instance monadErrorAff :: MonadError Error (Aff e ) where
170- throwError e = runFn2 _throwError nonCanceler e
158+ instance bindAff :: Bind (Aff e ) where
159+ bind fa f = runFn3 _bind alwaysCanceler fa f
171160
172- catch Error aff ex = attempt aff >>= either ex pure
161+ instance monadAff :: Monad ( Aff e )
173162
174- instance alt Aff :: Alt (Aff e ) where
175- alt a1 a2 = attempt a1 >>= either ( const a2 ) pure
163+ instance monadEffAff :: MonadEff e (Aff e ) where
164+ liftEff eff = runFn2 _liftEff nonCanceler eff
176165
177- instance plusAff :: Plus (Aff e ) where
178- empty = throwError $ error " Always fails"
166+ -- | Allows users to catch and throw errors on the error channel of the
167+ -- | asynchronous computation. See documentation in `purescript-transformers`.
168+ instance monadErrorAff :: MonadError Error (Aff e ) where
169+ throwError e = runFn2 _throwError nonCanceler e
179170
180- instance alternative Aff :: Alternative ( Aff e )
171+ catchError aff ex = attempt aff >>= either ex pure
181172
182- instance monadPlusAff :: MonadPlus (Aff e )
173+ instance altAff :: Alt (Aff e ) where
174+ alt a1 a2 = attempt a1 >>= either (const a2) pure
183175
184- instance monadRecAff :: MonadRec (Aff e ) where
185- tailRecM f a = go 0 f a
186- where
187- go size f a = do
188- e <- f a
189- case e of
190- Left a' | size < 100 -> go (size + 1) f a'
191- | otherwise -> later (tailRecM f a' )
192- Right b -> pure b
176+ instance plusAff :: Plus (Aff e ) where
177+ empty = throwError $ error " Always fails"
193178
194- instance monadContAff :: MonadCont (Aff e ) where
195- callCC f = makeAff (\eb cb -> runAff eb cb (f \a -> makeAff (\_ _ -> cb a)))
179+ instance alternativeAff :: Alternative (Aff e )
196180
197- instance semigroupCanceler :: Semigroup (Canceler e ) where
198- append (Canceler f1 ) (Canceler f2 ) = Canceler (\e -> (||) <$> f1 e <*> f2 e )
181+ instance monadPlusAff :: MonadPlus (Aff e )
199182
200- instance monoidCanceler :: Monoid (Canceler e ) where
201- mempty = Canceler (const (pure true))
183+ instance monadRecAff :: MonadRec (Aff e ) where
184+ tailRecM f a = go 0 f a
185+ where
186+ go size f a = do
187+ e <- f a
188+ case e of
189+ Left a' | size < 100 -> go (size + 1 ) f a'
190+ | otherwise -> later (tailRecM f a')
191+ Right b -> pure b
202192
203- foreign import _cancelWith :: forall e a. Fn3 (Canceler e ) (Aff e a ) (Canceler e ) (Aff e a )
193+ instance monadContAff :: MonadCont (Aff e ) where
194+ callCC f = makeAff (\eb cb -> runAff eb cb (f \a -> makeAff (\_ _ -> cb a)))
204195
205- foreign import _setTimeout :: forall e a. Fn3 (Canceler e ) Int (Aff e a ) (Aff e a )
196+ instance semigroupCanceler :: Semigroup (Canceler e ) where
197+ append (Canceler f1) (Canceler f2) = Canceler (\e -> (||) <$> f1 e <*> f2 e)
206198
207- foreign import _unsafeInterleaveAff :: forall e1 e2 a. Aff e1 a -> Aff e2 a
199+ instance monoidCanceler :: Monoid (Canceler e ) where
200+ mempty = Canceler (const (pure true ))
208201
209- foreign import _fork Aff :: forall e a. Fn2 (Canceler e ) (Aff e a ) (Aff e (Canceler e) )
202+ foreign import _cancelWith :: forall e a . Fn3 (Canceler e ) (Aff e a ) (Canceler e ) ( Aff e a )
210203
211- foreign import _make Aff :: forall e a. ((Error -> Eff e Unit) -> (a -> Eff e Unit) -> Eff e (Canceler e)) -> Aff e a
204+ foreign import _setTimeout :: forall e a . Fn3 ( Canceler e ) Int ( Aff e a ) ( Aff e a )
212205
213- foreign import _pure :: forall e a. Fn2 ( Canceler e ) a ( Aff e a )
206+ foreign import _unsafeInterleaveAff :: forall e1 e2 a . Aff e1 a -> Aff e2 a
214207
215- foreign import _throw Error :: forall e a. Fn2 (Canceler e ) Error (Aff e a )
208+ foreign import _forkAff :: forall e a . Fn2 (Canceler e ) (Aff e a ) ( Aff e ( Canceler e ) )
216209
217- foreign import _fmap :: forall e a b. Fn2 ( a -> b ) ( Aff e a ) ( Aff e b )
210+ foreign import _makeAff :: forall e a . (( Error -> Eff e Unit ) -> ( a -> Eff e Unit ) -> Eff e ( Canceler e )) -> Aff e a
218211
219- foreign import _bind :: forall e a b. Fn3 (Canceler e ) ( Aff e a ) ( a -> Aff e b ) ( Aff e b )
212+ foreign import _pure :: forall e a . Fn2 (Canceler e ) a ( Aff e a )
220213
221- foreign import _attempt :: forall e a. Fn3 ( forall x y . x -> Either x y ) ( forall x y . y -> Either x y ) (Aff e a ) ( Aff e (Either Error a) )
214+ foreign import _throwError :: forall e a . Fn2 ( Canceler e ) Error (Aff e a )
222215
223- foreign import _run Aff :: forall e a. Fn3 ( Error -> Eff e Unit ) ( a -> Eff e Unit ) (Aff e a ) (Eff e Unit )
216+ foreign import _fmap :: forall e a b . Fn2 ( a -> b ) (Aff e a ) (Aff e b )
224217
225- foreign import _lift Eff :: forall e a. Fn2 (Canceler e ) (Eff e a ) (Aff e a )
218+ foreign import _bind :: forall e a b . Fn3 (Canceler e ) (Aff e a ) (a -> Aff e b ) ( Aff e b )
226219
220+ foreign import _attempt :: forall e a . Fn3 (forall x y . x -> Either x y ) (forall x y . y -> Either x y ) (Aff e a ) (Aff e (Either Error a ))
227221
222+ foreign import _runAff :: forall e a . Fn3 (Error -> Eff e Unit ) (a -> Eff e Unit ) (Aff e a ) (Eff e Unit )
228223
224+ foreign import _liftEff :: forall e a . Fn2 (Canceler e ) (Eff e a ) (Aff e a )
0 commit comments