Skip to content

Commit 40eac43

Browse files
committed
simplify effect types, add a bunch of instances
1 parent e4682e5 commit 40eac43

File tree

3 files changed

+110
-70
lines changed

3 files changed

+110
-70
lines changed

MODULES.md

Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,29 @@
55
#### `Async`
66

77
``` purescript
8-
data Async :: # ! -> !
8+
data Async :: !
99
```
1010

11-
An effect constructor which accepts a row of effects. `Async e`
12-
represents the effect of asynchronous computations which perform effects
13-
`e` at some indeterminate point in the future.
11+
The effect of being asynchronous.
1412

1513
#### `EffA`
1614

1715
``` purescript
18-
type EffA e1 e2 a = Eff (async :: Async e1 | e2) a
16+
type EffA e a = Eff (async :: Async | e) a
1917
```
2018

21-
The `Eff` type for a computation which has asynchronous effects `e1` and
22-
synchronous effects `e2`.
19+
The `Eff` type for a computation which has asynchronous effects.
2320

2421
#### `Aff`
2522

2623
``` purescript
27-
data Aff e1 e2 a
24+
data Aff e a
2825
```
2926

30-
A computation with asynchronous effects `e1` and synchronous effects
31-
`e2`. The computation either errors or produces a value of type `a`.
27+
A computation with effects `e`. The computation either errors or
28+
produces a value of type `a`.
3229

33-
This is moral equivalent of `ErrorT (ContT Unit (EffA e1 e2)) a`.
30+
This is moral equivalent of `ErrorT (ContT Unit (EffA e)) a`.
3431

3532
The type implements `MonadEff` so it's easy to lift synchronous `Eff`
3633
computations into this type. As a result, there's basically no reason to
@@ -39,14 +36,14 @@ use `Eff` in a program that has some asynchronous computations.
3936
#### `PureAff`
4037

4138
``` purescript
42-
type PureAff a = forall e1 e2. Aff e1 e2 a
39+
type PureAff a = forall e. Aff e a
4340
```
4441

4542

4643
#### `launchAff`
4744

4845
``` purescript
49-
launchAff :: forall e1 e2 a. Aff e1 e2 a -> EffA e1 e2 Unit
46+
launchAff :: forall e a. Aff e a -> EffA e Unit
5047
```
5148

5249
Converts the asynchronous effect into a synchronous one. All values and
@@ -55,7 +52,7 @@ errors are ignored.
5552
#### `runAff`
5653

5754
``` purescript
58-
runAff :: forall e1 e2 a. (Error -> Eff e1 Unit) -> (a -> Eff e1 Unit) -> Aff e1 e2 a -> EffA e1 e2 Unit
55+
runAff :: forall e a. (Error -> Eff e Unit) -> (a -> Eff e Unit) -> Aff e a -> EffA e Unit
5956
```
6057

6158
Runs the asynchronous effect. You must supply an error callback and a
@@ -64,7 +61,7 @@ success callback.
6461
#### `makeAff`
6562

6663
``` purescript
67-
makeAff :: forall e1 e2 a. ((Error -> Eff e1 Unit) -> (a -> Eff e1 Unit) -> EffA e1 e2 Unit) -> Aff e1 e2 a
64+
makeAff :: forall e a. ((Error -> Eff e Unit) -> (a -> Eff e Unit) -> EffA e Unit) -> Aff e a
6865
```
6966

7067
Creates an asynchronous effect from a function that accepts error and
@@ -73,80 +70,107 @@ success callbacks.
7370
#### `attempt`
7471

7572
``` purescript
76-
attempt :: forall e1 e2 a. Aff e1 e2 a -> Aff e1 e2 (Either Error a)
73+
attempt :: forall e a. Aff e a -> Aff e (Either Error a)
7774
```
7875

7976
Promotes any error to the value level of the asynchronous monad.
8077

8178
#### `liftEff'`
8279

8380
``` purescript
84-
liftEff' :: forall e1 e2 a. Eff (err :: Exception | e2) a -> Aff e1 e2 (Either Error a)
81+
liftEff' :: forall e a. Eff (err :: Exception | e) a -> Aff e (Either Error a)
8582
```
8683

8784
Lifts a synchronous computation and makes explicit any failure from exceptions.
8885

8986
#### `semigroupAff`
9087

9188
``` purescript
92-
instance semigroupAff :: (Semigroup a) => Semigroup (Aff e1 e2 a)
89+
instance semigroupAff :: (Semigroup a) => Semigroup (Aff e a)
9390
```
9491

9592

9693
#### `monoidAff`
9794

9895
``` purescript
99-
instance monoidAff :: (Monoid a) => Monoid (Aff e1 e2 a)
96+
instance monoidAff :: (Monoid a) => Monoid (Aff e a)
10097
```
10198

10299

103100
#### `functorAff`
104101

105102
``` purescript
106-
instance functorAff :: Functor (Aff e1 e2)
103+
instance functorAff :: Functor (Aff e)
107104
```
108105

109106

110107
#### `applyAff`
111108

112109
``` purescript
113-
instance applyAff :: Apply (Aff e1 e2)
110+
instance applyAff :: Apply (Aff e)
114111
```
115112

116113

117114
#### `applicativeAff`
118115

119116
``` purescript
120-
instance applicativeAff :: Applicative (Aff e1 e2)
117+
instance applicativeAff :: Applicative (Aff e)
121118
```
122119

123120

124121
#### `bindAff`
125122

126123
``` purescript
127-
instance bindAff :: Bind (Aff e1 e2)
124+
instance bindAff :: Bind (Aff e)
128125
```
129126

130127

131128
#### `monadAff`
132129

133130
``` purescript
134-
instance monadAff :: Monad (Aff e1 e2)
131+
instance monadAff :: Monad (Aff e)
135132
```
136133

137134

138135
#### `monadEffAff`
139136

140137
``` purescript
141-
instance monadEffAff :: MonadEff e2 (Aff e1 e2)
138+
instance monadEffAff :: MonadEff e (Aff e)
142139
```
143140

144141

145142
#### `monadErrorAff`
146143

147144
``` purescript
148-
instance monadErrorAff :: MonadError Error (Aff e1 e2)
145+
instance monadErrorAff :: MonadError Error (Aff e)
149146
```
150147

151148
Allows users to catch and throw errors on the error channel of the
152-
asynchronous computation. See documentation in `purescript-transformers`.
149+
asynchronous computation. See documentation in `purescript-transformers`.
150+
151+
#### `altAff`
152+
153+
``` purescript
154+
instance altAff :: Alt (Aff e)
155+
```
156+
157+
158+
#### `plusAff`
159+
160+
``` purescript
161+
instance plusAff :: Plus (Aff e)
162+
```
163+
164+
165+
#### `alternativeAff`
166+
167+
``` purescript
168+
instance alternativeAff :: Alternative (Aff e)
169+
```
170+
171+
172+
#### `monadPlusAff`
173+
174+
``` purescript
175+
instance monadPlusAff :: MonadPlus (Aff e)
176+
```

README.md

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
An asynchronous effect monad for PureScript.
44

5-
The moral equivalent of `ErrorT (ContT Unit (Eff (async :: Async e1 | e2)) a`, for synchronous effects `e2`, asynchronous effects `e1`, and value `a`.
5+
The moral equivalent of `ErrorT (ContT Unit (Eff (async :: Async | e)) a`, for effects `e`.
66

7-
`Aff` lets you say goodbyte to monad transformers and callback hell!
7+
`Aff` lets you say goodbye to monad transformers and callback hell!
88

99
# Example
1010

@@ -35,13 +35,7 @@ deleteBlankLines path =
3535

3636
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).
3737

38-
`Aff` represents a computation with a synchronous component (for example, initiating an AJAX request), as well as an asynchronous component (retrieving an error or success response).
39-
40-
For maximum type safety, `Aff` separates the effects of the synchronous part from the asynchronous part. That is, an `Aff` computation may have one set of effects for its synchronous part, and another set for its asynchronous part.
41-
42-
Asynchronous effects are represented with an `async :: Async e1` effect label, where `e1` is the row of effects for actions that will occur at some indefinite point in the future.
43-
44-
The library contains instances for `Semigroup`, `Monoid`, `Apply`, `Applicative`, `Bind`, `Monad`, `MonadEff`, and `MonadError`. These instances allow you to compose `Aff`-ectful code as easily as `Eff`, as well as interop with existing `Eff` code.
38+
The library contains instances for `Semigroup`, `Monoid`, `Apply`, `Applicative`, `Bind`, `Monad`, `Alt`, `Plus`, `MonadPlus`, `MonadEff`, and `MonadError`. These instances allow you to compose `Aff`-ectful code as easily as `Eff`, as well as interop with existing `Eff` code.
4539

4640
## Escaping Callback Hell
4741

@@ -50,7 +44,7 @@ Hopefully, you're using libraries that already use the `Aff` type, so you don't
5044
If you're building your own library, or you have to interact with some native code that expects callbacks, then *purescript-aff* provides a `makeAff` function you can use:
5145

5246
```purescript
53-
makeAff :: forall e1 e2 a. ((Error -> Eff e1 Unit) -> (a -> Eff e1 Unit) -> EffA e1 e2 Unit) -> Aff e1 e2 a
47+
makeAff :: forall e a. ((Error -> Eff e Unit) -> (a -> Eff e Unit) -> EffA e Unit) -> Aff e a
5448
```
5549

5650
This function expects you to provide a handler, which should call a user-supplied error callback or success callback with the result of the asynchronous computation.
@@ -68,13 +62,13 @@ function ajaxGet(callback) { // accepts a callback
6862
}
6963
}
7064
}
71-
""" :: forall e1 e2. (Response -> Eff e1 Unit) -> Request -> EffA e1 (ajax :: Ajax | e2) Unit
65+
""" :: forall e. (Response -> Eff e Unit) -> Request -> EffA e Unit
7266
```
7367

7468
We can wrap this into an asynchronous computation like so:
7569

7670
```purescript
77-
ajaxGet' :: forall e1 e2. Request -> Aff e1 (ajax :: Ajax | e2) Response
71+
ajaxGet' :: forall e. Request -> Aff e Response
7872
ajaxGet' req = makeAff (\error success -> ajaxGet success req)
7973
```
8074

@@ -105,23 +99,34 @@ do e <- liftEff' myExcFunc
10599
liftEff $ either (const $ trace "Oh noes!") (const $ trace "Yays!") e
106100
```
107101

108-
## Exceptions
102+
## Failure
109103

110104
The `Aff` monad has error handling baked in, so ordinarily you don't have to worry about it.
111105

112106
If you want to attempt a computation but recover from failure, you can use the `attempt` function:
113107

114108
```purescript
115-
attempt :: forall e1 e2 a. Aff e1 e2 a -> Aff e1 e2 (Either Error a)
109+
attempt :: forall e a. Aff e a -> Aff e (Either Error a)
116110
```
117111

118-
This returns an `Either Error a` you can use to recover gracefully from failure.
112+
This returns an `Either Error a` that you can use to recover from failure.
119113

120114
```purescript
121115
do e <- attempt $ Ajax.get "http://foo.com"
122116
liftEff $ either (const $ trace "Oh noes!") (const $ trace "Yays!") e
123117
```
124118

119+
### Alt
120+
121+
Because `Aff` has an `Alt` instance, you may also use the operator `<|>` to provide an alternative computation in the event of failure:
122+
123+
```purescript
124+
do result <- Ajax.get "http://foo.com" <|> Ajax.get "http://bar.com"
125+
return result
126+
```
127+
128+
### MonadError
129+
125130
`Aff` has a `MonadError` instance, which comes with two functions: `catchError`, and `throwError`.
126131

127132
These are defined in [purescript-transformers](http://github.com/purescript/purescript-transformers).

0 commit comments

Comments
 (0)