Skip to content

Commit 69bf7ed

Browse files
committed
README edits
1 parent 7576856 commit 69bf7ed

File tree

2 files changed

+61
-20
lines changed

2 files changed

+61
-20
lines changed

README.md

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,17 @@ asynchronously without any callbacks. Error handling is baked in so you only
3737
deal with it when you want to.
3838

3939
The library contains instances for `Semigroup`, `Monoid`, `Apply`,
40-
`Applicative`, `Bind`, `Monad`, `Alt`, `Plus`, `MonadEff`, and `MonadError`.
41-
These instances allow you to compose asynchronous code as easily as `Eff`, as
42-
well as interop with existing `Eff` code.
40+
`Applicative`, `Bind`, `Monad`, `Alt`, `Plus`, `MonadEff`, `MonadError`, and
41+
`Parallel`. These instances allow you to compose asynchronous code as easily
42+
as `Eff`, as well as interop with existing `Eff` code.
4343

4444
## Escaping Callback Hell
4545

4646
Hopefully, you're using libraries that already use the `Aff` type, so you
4747
don't even have to think about callbacks!
4848

49-
If you're building your own library, then *purescript-aff* provides a
50-
`makeAff` function:
49+
If you're building your own library, then you can make an `Aff` from
50+
low-level `Eff` callbacks with `makeAff`.
5151

5252
```purescript
5353
makeAff :: forall eff a. ((Either Error a -> Eff eff Unit) -> Eff eff (Canceler eff)) -> Aff eff a
@@ -60,8 +60,8 @@ You should also return `Canceler`, which is just a cleanup effect. Since
6060
`Aff` threads may be killed, all asynchronous operations should provide a
6161
mechanism for unscheduling it.
6262

63-
*purescript-aff* also provides functions for easily binding FFI definitions in
64-
`Control.Monad.Aff.Compat`.
63+
`Control.Monad.Aff.Compat` provides functions for easily binding FFI
64+
definitions:
6565

6666
```javascript
6767
exports._ajaxGet = function (request) { // accepts a request
@@ -108,12 +108,9 @@ example = do
108108
## Eff
109109

110110
All purely synchronous computations (`Eff`) can be lifted to asynchronous
111-
computations with `liftEff` defined in `Control.Monad.Eff.Class` (see
112-
[here](https://github.com/purescript/purescript-eff)).
111+
computations with `liftEff` defined in `Control.Monad.Eff.Class`.
113112

114113
```purescript
115-
import Control.Monad.Eff.Class
116-
117114
liftEff $ log "Hello world!"
118115
```
119116

@@ -212,18 +209,47 @@ example = do
212209
## AVars
213210

214211
The `Control.Monad.Aff.AVar` module contains asynchronous variables, which
215-
are very similar to Haskell's `MVar`. These can be used as low-level building
216-
blocks for asynchronous programs.
212+
are very similar to Haskell's `MVar`.
213+
214+
`AVar`s represent a value that is either full or empty. Calling `takeVar` on
215+
an empty `AVar` will queue until it is filled by a matching `putVar`.
217216

218217
```purescript
219-
example = d
220-
v <- makeEmptyVar
218+
example = do
219+
var <- makeEmptyVar
220+
_ <- forkAff do
221+
value <- takeVar var
222+
log $ "Got a value: " <> value
221223
_ <- forkAff do
222-
delay (Milliseconds 50.0)
223-
putVar v 1.0
224-
a <- takeVar v
225-
log ("Succeeded with " <> show a)
224+
delay (Milliseconds 100.0)
225+
putVar var "hello"
226+
pure unit
226227
```
228+
```
229+
(Waits 100ms)
230+
> Got a value: hello
231+
```
232+
233+
Likewise, calling `putVar` will queue until it is taken:
234+
235+
```purescript
236+
example = do
237+
var <- makeEmptyVar
238+
_ <- forkAff do
239+
delay (Milliseconds 100.0)
240+
value <- takeVar var
241+
log $ "Got a value: " <> value
242+
putVar var "hello"
243+
log "Value taken"
244+
```
245+
```
246+
(Waits 100ms)
247+
> Value taken
248+
> Got a value: hello
249+
```
250+
251+
These combinators (and a few more) can be used as the building blocks for
252+
complex asynchronous coordination.
227253

228254
## Parallel Execution
229255

test/Test/Main.purs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import Prelude
44

55
import Control.Alt ((<|>))
66
import Control.Monad.Aff (Aff, Canceler(..), runAff_, launchAff, makeAff, try, bracket, generalBracket, delay, forkAff, suspendAff, joinFiber, killFiber, never, supervise)
7+
import Control.Monad.Aff.AVar (AVAR, makeEmptyVar, takeVar, putVar)
78
import Control.Monad.Eff (Eff, runPure)
89
import Control.Monad.Eff.Class (class MonadEff, liftEff)
910
import Control.Monad.Eff.Console (CONSOLE)
@@ -24,7 +25,7 @@ import Data.Time.Duration (Milliseconds(..))
2425
import Data.Traversable (traverse)
2526
import Test.Assert (assert', ASSERT)
2627

27-
type TestEffects eff = (assert ASSERT, console CONSOLE, ref REF, exception EXCEPTION | eff)
28+
type TestEffects eff = (assert ASSERT, console CONSOLE, ref REF, exception EXCEPTION, avar AVAR | eff)
2829
type TestEff eff = Eff (TestEffects eff)
2930
type TestAff eff = Aff (TestEffects eff)
3031

@@ -514,6 +515,19 @@ test_fiber_apply = assert "fiber/apply" do
514515
n ← readRef ref
515516
pure (a == 22 && b == 22 && n == 1)
516517

518+
test_avar_order eff. TestAff eff Unit
519+
test_avar_order = assert "avar/order" do
520+
ref ← newRef ""
521+
var ← makeEmptyVar
522+
f1 ← forkAff do
523+
delay (Milliseconds 10.0)
524+
value ← takeVar var
525+
modifyRef ref (_ <> value)
526+
putVar var "foo"
527+
modifyRef ref (_ <> "taken")
528+
joinFiber f1
529+
eq "takenfoo" <$> readRef ref
530+
517531
test_parallel_stack eff. TestAff eff Unit
518532
test_parallel_stack = assert "parallel/stack" do
519533
ref ← newRef 0
@@ -558,6 +572,7 @@ main = do
558572
test_parallel_alt_sync
559573
test_parallel_mixed
560574
test_kill_parallel_alt
575+
test_avar_order
561576
test_fiber_map
562577
test_fiber_apply
563578
-- Turn on if we decide to schedule forks

0 commit comments

Comments
 (0)