Skip to content

Commit 474897e

Browse files
1eyewonderTheAngryByrd
authored andcommitted
Added documentation
1 parent ae08b58 commit 474897e

File tree

8 files changed

+189
-1
lines changed

8 files changed

+189
-1
lines changed

gitbook/SUMMARY.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,17 @@
100100
* [ofResult](validation/ofResult.md)
101101
* [Operators](validation/operators.md)
102102
* [Result.tryCreate](validation/tryCreate.md)
103+
* [Computation Expression](validation/ce.md)
104+
105+
* [AsyncValidation](asyncValidation/index.md)
106+
* [map2](asyncValidation/map2.md)
107+
* [map3](asyncValidation/map3.md)
108+
* [apply](asyncValidation/apply.md)
109+
* [ofResult](asyncValidation/ofResult.md)
110+
* [Operators](asyncValidation/operators.md)
111+
* [Computation Expression](asyncValidation/ce.md)
103112

104113
* [Test](test/index.md)
105114
* [testing](test/testing.md)
106115
* [testing-nested1](test/testing-nested1.md)
107-
* [testing-nested2](test/testing-nested2.md)
116+
* [testing-nested2](test/testing-nested2.md)

gitbook/asyncValidation/apply.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
## AsyncValidation.apply
2+
3+
Namespace: `FsToolkit.ErrorHandling`
4+
5+
Function Signature:
6+
7+
```fsharp
8+
Async<Result<('a -> 'b), 'c list>>
9+
-> Async<Result<'a, 'c list>>
10+
-> Async<Result<'b, 'c list>>
11+
```
12+
13+
## Examples

gitbook/asyncValidation/ce.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
## AsyncValidation Computation Expression
2+
3+
Namespace: `FsToolkit.ErrorHandling`
4+
5+
The `AsyncValidation` type is defined as:
6+
7+
```fsharp
8+
type AsyncValidation<'a,'err> = Async<Result<'a, 'err list>>
9+
```
10+
11+
This CE can take advantage of the [and! operator](https://github.com/fsharp/fslang-suggestions/issues/579) to join multiple error results into a list.
12+
13+
## Examples
14+
15+
The example from [AsyncValidation.map3](../asyncValidation/map3.md#example-1) can be solved using the `asyncValidation` computation expression as below:
16+
17+
```fsharp
18+
// Result<string, string> -> Async<Result<string, string>>
19+
let downloadAsync stuff = async {
20+
return stuff
21+
}
22+
23+
// AsyncValidation<string, string>
24+
let addResult = asyncValidation {
25+
let! x = downloadAsync (Ok "I")
26+
and! y = downloadAsync (Ok "am")
27+
and! z = downloadAsync (Ok "async!")
28+
return sprintf "%s %s %s" x y z
29+
}
30+
31+
// result = async { return Ok "I am async!" }
32+
33+
// AsyncValidation<string, string>
34+
let addResult = asyncValidation {
35+
let! x = downloadAsync (Error "Am")
36+
and! y = downloadAsync (Error "I")
37+
and! z = downloadAsync (Error "async?")
38+
return sprintf "%s %s %s" x y z
39+
}
40+
41+
// result = async { return Error [ "Am"; "I"; "async?" ] }
42+
```
43+

gitbook/asyncValidation/index.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
## AsyncValidation
2+
3+
Namespace: `FsToolkit.ErrorHandling`
4+
5+
This module provides utility functions and infix operators to work with `Async<Result<'a, 'b list>>`.

gitbook/asyncValidation/map2.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
## AsyncValidation.map2
2+
3+
Namespace: `FsToolkit.ErrorHandling`
4+
5+
Function Signature:
6+
7+
```fsharp
8+
('a -> 'b -> 'c)
9+
-> Async<Result<'a, 'd list>>
10+
-> Async<Result<'b, 'd list>>
11+
-> Async<Result<'c, 'd list>>
12+
```
13+
14+
Like [Result.map2](../result/map2.md), but collects the errors from both arguments.
15+
16+
## Examples

gitbook/asyncValidation/map3.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
## AsyncAsyncValidation.map3
2+
3+
Namespace: `FsToolkit.ErrorHandling`
4+
5+
Function Signature:
6+
7+
```
8+
('a -> 'b -> 'c -> 'd)
9+
-> Async<Result<'a, 'e list>>
10+
-> Async<Result<'b, 'e list>>
11+
-> Async<Result<'c, 'e list>>
12+
-> Async<Result<'d, 'e list>>
13+
```
14+
15+
Like [Result.map3](../result/map3.md), but collects the errors from all arguments.
16+
17+
## Examples
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
## AsyncValidation.ofResult
2+
3+
Namespace: `FsToolkit.ErrorHandling`
4+
5+
Function Signature:
6+
7+
```fsharp
8+
Result<'a, 'b> -> Async<Result<'a, 'b list>>
9+
```
10+
11+
Simply wraps the error in a list and makes the result async.
12+
13+
## Examples
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
## AsyncValidation Infix Operators
2+
3+
Namespace: `FsToolkit.ErrorHandling.Operator.AsyncValidation`
4+
5+
FsToolkit.ErrorHandling provides the standard infix operators for `map` (`<!>`), `apply` (`<*>`), and `bind` (`>>=`) to work with `Result<'a, 'b list>`.
6+
7+
There are also variants of the `map` and `apply` operators (`<!^>` and `<*^>`) that accept `Result<'a, 'b>` (non-list) as the right-hand argument.
8+
9+
## Examples
10+
11+
### Example 1
12+
13+
Assume that we have following types and functions:
14+
15+
```fsharp
16+
type Latitude = private Latitude of float with
17+
// float -> Async<Result<Latitude, string list>>
18+
static member TryCreate (lat : float) =
19+
// ...
20+
21+
type Longitude = private Longitude of float with
22+
// float -> Async<Result<Longitude, string list>>
23+
static member TryCreate (lng : float) =
24+
// ...
25+
26+
type Tweet = private Tweet of string with
27+
// string -> Async<Result<Tweet, string list>>
28+
static member TryCreate (tweet : string) =
29+
// ...
30+
31+
// Latitude -> Longitude -> Tweet -> CreatePostRequest
32+
let createPostRequest lat long tweet =
33+
// ...
34+
```
35+
36+
We can make use of the standard operators in the AsyncValidation Operators module to perform the asyncValidation of the incoming request and capture all the errors as shown below:
37+
38+
```fsharp
39+
open FsToolkit.ErrorHandling.Operator.AsyncValidation
40+
41+
// float -> float -> string -> Async<Result<CreatePostRequest, string list>>
42+
let validateCreatePostRequest lat lng tweet =
43+
createPostRequest
44+
<!> Latitude.TryCreate lat
45+
<*> Longitude.TryCreate lng
46+
<*> Tweet.TryCreate tweet
47+
```
48+
49+
By using the `AsyncValidation` operators instead of the `Result` operators, we collect all the errors:
50+
```fsharp
51+
validateCreatePostRequest 300. 400. ""
52+
// Error
53+
["300.0 is a invalid latitude value"
54+
"400.0 is a invalid longitude value"
55+
"Tweet shouldn't be empty"]
56+
```
57+
58+
### Example 2
59+
60+
In the above example, all the `TryCreate` functions return a string list as the error type (`Async<Result<'a, string list>>`). If these functions instead returned `Async<Result<'a, string>>` (only a single error), we can use `<*^>` and `<!^>` to get the same result:
61+
62+
63+
```fsharp
64+
open FsToolkit.ErrorHandling.Operator.AsyncValidation
65+
66+
// float -> float -> string -> Async<Result<CreatePostRequest, string list>>
67+
let validateCreatePostRequest lat lng tweet =
68+
createPostRequest
69+
<!^> Latitude.TryCreate lat
70+
<*^> Longitude.TryCreate lng
71+
<*^> Tweet.TryCreate tweet
72+
```

0 commit comments

Comments
 (0)