|
| 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