You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+26-20Lines changed: 26 additions & 20 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,16 +6,16 @@
6
6
7
7
An asynchronous effect monad for PureScript.
8
8
9
-
The moral equivalent of `ErrorT (ContT Unit (Eff e) a`, for effects `e`.
9
+
The moral equivalent of `ErrorT (ContT Unit (Eff e)) a`, for effects `e`.
10
10
11
11
`Aff` lets you say goodbye to monad transformers and callback hell!
12
12
13
13
# Example
14
14
15
15
```purescript
16
-
main = launchAff $
17
-
do response <- Ajax.get "http://foo.bar"
18
-
liftEff $ log response.body
16
+
main = launchAff do
17
+
response <- Ajax.get "http://foo.bar"
18
+
liftEff $ log response.body
19
19
```
20
20
21
21
See the [tests](https://github.com/slamdata/purescript-aff/blob/master/test/Test/Main.purs) for more examples.
@@ -33,10 +33,10 @@ bower install purescript-aff
33
33
An example of `Aff` is shown below:
34
34
35
35
```purescript
36
-
deleteBlankLines path =
37
-
do contents <- loadFile path
38
-
let contents' = S.join "\n" $ A.filter (\a -> S.length a > 0) (S.split "\n" contents)
39
-
saveFile path contents'
36
+
deleteBlankLines path = do
37
+
contents <- loadFile path
38
+
let contents' = S.join "\n" $ A.filter (\a -> S.length a > 0) (S.split "\n" contents)
39
+
saveFile path contents'
40
40
```
41
41
42
42
This looks like ordinary, synchronous, imperative code, but actually operates asynchronously without any callbacks. Error handling is baked in so you only deal with it when you want to.
@@ -149,23 +149,23 @@ Here's an example of how you can use them:
149
149
150
150
```purescript
151
151
do resp <- (Ajax.get "http://foo.com") `catchError` (const $ pure defaultResponse)
152
-
if resp.statusCode != 200 then throwError myErr
152
+
if resp.statusCode != 200 then throwError myErr
153
153
else pure resp.body
154
154
```
155
155
156
156
Thrown exceptions are propagated on the error channel, and can be recovered from using `attempt` or `catchError`.
157
157
158
158
## Forking
159
159
160
-
Using the `forkAff`, you can "fork" an asynchronous computation, which means
160
+
Using the `forkAff`, you can "fork" an asynchronous computation, which means
161
161
that its activities will not block the current thread of execution:
162
162
163
163
```purescript
164
164
forkAff myAff
165
165
```
166
166
167
-
Because Javascript is single-threaded, forking does not actually cause the
168
-
computation to be run in a separate thread. Forking just allows the subsequent
167
+
Because Javascript is single-threaded, forking does not actually cause the
168
+
computation to be run in a separate thread. Forking just allows the subsequent
169
169
actions to execute without waiting for the forked computation to complete.
170
170
171
171
If the asynchronous computation supports it, you can "kill" a forked computation
@@ -191,28 +191,34 @@ The `Control.Monad.Aff.AVar` module contains asynchronous variables, which are v
191
191
```purescript
192
192
do v <- makeVar
193
193
forkAff (later $ putVar v 1.0)
194
-
a <- takeVar v
194
+
a <- takeVar v
195
195
liftEff $ log ("Succeeded with " ++ show a)
196
196
```
197
197
198
-
You can use these constructs as one-sided blocking queues, which suspend (if
198
+
You can use these constructs as one-sided blocking queues, which suspend (if
199
199
necessary) on `take` operations, or as asynchronous, empty-or-full variables.
200
200
201
201
## Parallel Execution
202
202
203
-
If you only need the power of `Applicative`, then instead of using the monadic `Aff`, you can use the `Par` newtype wrapper defined in `Control.Monad.Aff.Par`.
203
+
There are `MonadPar` and `MonadRace` instances defined for `Aff`, allowing for parallel execution of `Aff` computations.
204
204
205
-
This provides parallel instances of `Apply` and `Alt`.
205
+
There are two ways of taking advantage of these instances - directly through the `par` and `race` functions from these classes, or by using the `Parallel` newtype wrapper that enables parallel behaviours through the `Applicative` and `Alternative` operators.
206
206
207
-
In the following example, two Ajax requests are initiated simultaneously (rather than in sequence, as they would be for `Aff`):
207
+
In the following example, using the newtype, two Ajax requests are initiated simultaneously (rather than in sequence, as they would be for `Aff`):
208
208
209
209
```purescript
210
-
runPar (f <$> Par (Ajax.get "http://foo.com") <*> Par (Ajax.get "http://foo.com"))
The `(<|>)` operator of the `Alt` instance of `Par` allows you to race two asynchronous computations, and use whichever value comes back first (or the first error, if both err).
213
+
And the equivalent using the `MonadPar` function directly:
214
214
215
-
The `runPar` function allows you to unwrap the `Aff` and return to normal monadic (sequential) composition.
215
+
```purescript
216
+
par f (Ajax.get "http://foo.com") (Ajax.get "http://foo.com")
217
+
```
218
+
219
+
The `race` function from `MonadPar` or the `(<|>)` operator of the `Alt` instance of `Parallel` allows you to race two asynchronous computations, and use whichever value comes back first (or the first error, if both err).
220
+
221
+
The `runParallel` function allows you to unwrap the `Aff` and return to normal monadic (sequential) composition.
216
222
217
223
A parallel computation can be canceled if both of its individual components can be canceled.
0 commit comments