diff --git a/gitbook/SUMMARY.md b/gitbook/SUMMARY.md index e636fd0e..210bd298 100644 --- a/gitbook/SUMMARY.md +++ b/gitbook/SUMMARY.md @@ -73,7 +73,7 @@ * [map](resultOption/map.md) * [map2](resultOption/map2.md) * [map3](resultOption/map3.md) - * [mapError](pr.md) + * [mapError](resultOption/mapError.md) * [Operators](resultOption/operators.md) * [zip](resultOption/zip.md) * [zipError](resultOption/zipError.md) @@ -96,8 +96,8 @@ * [mapError](asyncResult/mapError.md) * [Operators](asyncResult/operators.md) * [Other Functions](asyncResult/others.md) - * [zip](pr.md) - * [zipError](pr.md) + * [zip](asyncResult/zip.md) + * [zipError](asyncResult/zipError.md) * List * [traverseAsyncResultM](list/traverseAsyncResultM.md) * [sequenceAsyncResultM](list/sequenceAsyncResultM.md) @@ -139,35 +139,34 @@ * [ofResult](asyncResultOption/ofResult.md) * Task - * [apply](pr.md) - * [bind](pr.md) - * [bindV](pr.md) - * [catch](pr.md) - * [Computation Expression](pr.md) - * [ignore](pr.md) - * [map](pr.md) - * [mapV](pr.md) - * [map2](pr.md) - * [map3](pr.md) - * [ofUnit](pr.md) - * [zip](pr.md) + * [apply](task/apply.md) + * [bind](task/bind.md) + * [bindV](task/bindV.md) + * [catch](task/catch.md) + * [Computation Expression](task/ce.md) + * [ignore](task/ignore.md) + * [map](task/map.md) + * [mapV](task/mapV.md) + * [map2](task/map2.md) + * [map3](task/map3.md) + * [zip](task/zip.md) * Transforms * [ofUnit](task/ofUnit.md) * TaskOption - * [apply](pr.md) - * [bind](pr.md) + * [apply](taskOption/apply.md) + * [bind](taskOption/bind.md) * [Computation Expression](taskOption/ce.md) - * [either](pr.md) - * [map](pr.md) - * [some](pr.md) - * [zip](pr.md) + * [either](taskOption/either.md) + * [map](taskOption/map.md) + * [Other Functions](taskOption/others.md) + * [zip](taskOption/zip.md) * TaskResult * [apply](taskResult/apply.md) * [bind](taskResult/bind.md) * [check](taskResult/check.md) - * [catch](pr.md) + * [catch](taskResult/catch.md) * [Computation Expression](taskResult/ce.md) * [ignore](taskResult/ignore.md) * [map](taskResult/map.md) @@ -177,8 +176,8 @@ * [Operators](taskResult/operators.md) * [Other Functions](taskResult/others.md) * [error](taskResult/error.md) - * [zip](pr.md) - * [zipError](pr.md) + * [zip](taskResult/zip.md) + * [zipError](taskResult/zipError.md) * Lists * [traverseTaskResultM](list/traverseTaskResultM.md) * [sequenceTaskResultM](list/sequenceTaskResultM.md) @@ -203,13 +202,13 @@ * [apply](validation/apply.md) * [Computation Expression](validation/ce.md) * [error](validation/error.md) - * [map](pr.md) + * [map](validation/map.md) * [map2](validation/map2.md) * [map3](validation/map3.md) - * [mapError](pr.md) - * [mapErrors](pr.md) + * [mapError](validation/mapError.md) + * [mapErrors](validation/mapErrors.md) * [Operators](validation/operators.md) - * [zip](pr.md) + * [zip](validation/zip.md) * Transforms * [ofChoice](validation/ofChoice.md) * [ofResult](validation/ofResult.md) @@ -218,13 +217,13 @@ * [apply](asyncValidation/apply.md) * [Computation Expression](asyncValidation/ce.md) * [error](asyncValidation/error.md) - * [map](pr.md) + * [map](asyncValidation/map.md) * [map2](asyncValidation/map2.md) * [map3](asyncValidation/map3.md) - * [mapError](pr.md) - * [mapErrors](pr.md) + * [mapError](asyncValidation/mapError.md) + * [mapErrors](asyncValidation/mapErrors.md) * [Operators](asyncValidation/operators.md) - * [zip](pr.md) + * [zip](asyncValidation/zip.md) * Transforms * [ofChoice](asyncValidation/ofChoice.md) * [ofResult](asyncValidation/ofResult.md) diff --git a/gitbook/asyncResult/zip.md b/gitbook/asyncResult/zip.md new file mode 100644 index 00000000..c74635c4 --- /dev/null +++ b/gitbook/asyncResult/zip.md @@ -0,0 +1,32 @@ +# AsyncResult.zip + +Namespace: `FsToolkit.ErrorHandling` + +## Function Signature + +```fsharp +Async> -> Async> -> Async> +``` + +## Examples + +### Example 1 + +```fsharp +let result = AsyncResult.zip (AsyncResult.ok 1) (AsyncResult.ok 2) +// async { Ok (1, 2) } +``` + +### Example 2 + +```fsharp +let result = AsyncResult.zip (AsyncResult.ok 1) (AsyncResult.error "Bad") +// async { Error "Bad" } +``` + +### Example 3 + +```fsharp +let result = AsyncResult.zip (AsyncResult.error "Bad1") (AsyncResult.error "Bad2") +// async { Error "Bad1" } +``` diff --git a/gitbook/asyncResult/zipError.md b/gitbook/asyncResult/zipError.md new file mode 100644 index 00000000..c2b0b6db --- /dev/null +++ b/gitbook/asyncResult/zipError.md @@ -0,0 +1,32 @@ +# AsyncResult.zipError + +Namespace: `FsToolkit.ErrorHandling` + +## Function Signature + +```fsharp +Async> -> Async> -> Async> +``` + +## Examples + +### Example 1 + +```fsharp +let result = AsyncResult.zipError (AsyncResult.ok 1) (AsyncResult.ok 2) +// async { Ok 1 } +``` + +### Example 2 + +```fsharp +let result = AsyncResult.zipError (AsyncResult.ok 1) (AsyncResult.error "Bad") +// async { Ok 1 } +``` + +### Example 3 + +```fsharp +let result = AsyncResult.zipError (AsyncResult.error "Bad1") (AsyncResult.error "Bad2") +// async { Error("Bad1", "Bad2") } +``` diff --git a/gitbook/asyncValidation/map.md b/gitbook/asyncValidation/map.md new file mode 100644 index 00000000..c4d8c0b5 --- /dev/null +++ b/gitbook/asyncValidation/map.md @@ -0,0 +1,41 @@ +# AsyncValidation.map + +Namespace: `FsToolkit.ErrorHandling` + +`map` applies a transformation to the value inside an `AsyncValidation` if it represents a successful result (`Ok`). It allows you to perform a computation on the value while preserving the success/error status of the original `AsyncValidation`. If the original `AsyncValidation` is an `Error`, `map` does nothing and returns the same `Error` unchanged. + +## Function Signature + +```fsharp +('okInput -> 'okOutput) -> AsyncValidation<'okInput, 'error> -> AsyncValidation<'okOutput, 'error> +``` + +## Examples + +Take the following functions for example + +```fsharp +// string -> int +let remainingCharacters (prompt: string) = + 280 - prompt.Length +``` + +### Example 1 + +```fsharp +let validation = + AsyncValidation.ok "foo" // AsyncValidation + |> AsyncValidation.map remainingCharacters // AsyncValidation + +// async { Ok 277 } +``` + +### Example 2 + +```fsharp +let result = + AsyncValidation.error "bad things happened" // AsyncValidation + |> AsyncValidation.map remainingCharacters // AsyncValidation + +// async { Error ["bad things happened"] } +``` diff --git a/gitbook/asyncValidation/mapError.md b/gitbook/asyncValidation/mapError.md new file mode 100644 index 00000000..8194cdba --- /dev/null +++ b/gitbook/asyncValidation/mapError.md @@ -0,0 +1,44 @@ +# AsyncValidation.mapError + +Namespace: `FsToolkit.ErrorHandling` + +`mapError` takes an async validation and a normal function and returns a new async validation value based on the input error value and the function + +## Function Signature + +```fsharp +('errorInput -> 'errorOutput) -> AsyncValidation<'ok, 'errorInput> + -> AsyncValidation<'ok, 'errorOutput> +``` + +## Examples + +Take the following functions for example + +```fsharp +// string -> int +let getErrorCode (message: string) = + match message with + | "bad things happened" -> 1 + | _ -> 0 +``` + +### Example 1 + +```fsharp +let result = + AsyncValidation.ok "all good" // AsyncValidation + |> AsyncValidation.mapError getErrorCode // AsyncValidation + +// async { Ok "all good" } +``` + +### Example 2 + +```fsharp +let result = + AsyncValidation.error "bad things happened" // AsyncValidation + |> AsyncValidation.mapError getErrorCode // AsyncValidation + +// async { Error [1] } +``` diff --git a/gitbook/asyncValidation/mapErrors.md b/gitbook/asyncValidation/mapErrors.md new file mode 100644 index 00000000..8765fdfe --- /dev/null +++ b/gitbook/asyncValidation/mapErrors.md @@ -0,0 +1,44 @@ +# AsyncValidation.mapErrors + +Namespace: `FsToolkit.ErrorHandling` + +Similar to [AsyncValidation.mapError](../asyncValidation/mapError.md), except that the mapping function is passed the full list of errors, rather than each one individually. + +## Function Signature + +```fsharp +('errorInput list -> 'errorOutput list) -> AsyncValidation<'ok, 'errorInput> + -> AsyncValidation<'ok, 'errorOutput> +``` + +## Examples + +Take the following functions for example + +```fsharp +// string -> int +let getErrorCode (messages: string list) = + match messages |> List.tryFind ((=) "bad things happened") with + | Some _ -> [1] + | _ -> [0] +``` + +### Example 1 + +```fsharp +let result = + AsyncValidation.ok "all good" // AsyncValidation + |> AsyncValidation.mapErrors getErrorCode // AsyncValidation + +// async { Ok "all good" } +``` + +### Example 2 + +```fsharp +let result : AsyncValidation = + AsyncValidation.error "bad things happened" // AsyncValidation + |> AsyncValidation.mapErrors getErrorCode // AsyncValidation + +// async { Error [1] } +``` diff --git a/gitbook/asyncValidation/zip.md b/gitbook/asyncValidation/zip.md new file mode 100644 index 00000000..03324dee --- /dev/null +++ b/gitbook/asyncValidation/zip.md @@ -0,0 +1,32 @@ +# AsyncValidation.zip + +Namespace: `FsToolkit.ErrorHandling` + +## Function Signature + +```fsharp +AsyncValidation<'leftOk, 'error> -> AsyncValidation<'rightOk, 'error> -> AsyncValidation<'leftOk * 'rightOk, 'error> +``` + +## Examples + +### Example 1 + +```fsharp +let result = AsyncValidation.zip (AsyncValidation.ok 1) (AsyncValidation.ok 2) +// async { Ok (1, 2) } +``` + +### Example 2 + +```fsharp +let result = AsyncValidation.zip (AsyncValidation.ok 1) (AsyncValidation.error "Bad") +// async { Error [ "Bad" ] } +``` + +### Example 3 + +```fsharp +let result = AsyncValidation.zip (AsyncValidation.error "Bad1") (AsyncValidation.error "Bad2") +// async { Error [ "Bad1"; "Bad2" ] } +``` diff --git a/gitbook/result/map.md b/gitbook/result/map.md index 6ecaec08..cd9b86c9 100644 --- a/gitbook/result/map.md +++ b/gitbook/result/map.md @@ -7,8 +7,7 @@ Namespace: `FsToolkit.ErrorHandling` ## Function Signature ```fsharp -('okInput -> 'okOutput) -> Result<'okInput, 'error> - -> Result<'okOutput, 'error> +('okInput -> 'okOutput) -> Result<'okInput, 'error> -> Result<'okOutput, 'error> ``` ## Examples @@ -26,7 +25,7 @@ let remainingCharacters (prompt: string) = ```fsharp let result = Ok "foo" // Result - |> ResultOption.map remainingCharacters // Result + |> Result.map remainingCharacters // Result // Ok 277 ``` @@ -36,7 +35,7 @@ let result = ```fsharp let result = Error "bad things happened" // Result - |> ResultOption.map remainingCharacters // Result + |> Result.map remainingCharacters // Result // Error "bad things happened" ``` diff --git a/gitbook/result/mapError.md b/gitbook/result/mapError.md index 8e6774cf..ca3da393 100644 --- a/gitbook/result/mapError.md +++ b/gitbook/result/mapError.md @@ -1,4 +1,4 @@ -# Result.mapError +# Result.mapError Namespace: `FsToolkit.ErrorHandling` @@ -27,10 +27,10 @@ let getErrorCode (message: string) = ```fsharp let result = - Ok "bad things happened" // Result - |> ResultOption.mapError getErrorCode // Result + Ok "all good" // Result + |> Result.mapError getErrorCode // Result -// Ok "bad things happened" +// Ok "all good" ``` ### Example 2 @@ -38,7 +38,7 @@ let result = ```fsharp let result = Error "bad things happened" // Result - |> ResultOption.mapError getErrorCode // Result + |> Result.mapError getErrorCode // Result // Error 1 ``` diff --git a/gitbook/result/zipError.md b/gitbook/result/zipError.md index c0563f6d..9a2a0d40 100644 --- a/gitbook/result/zipError.md +++ b/gitbook/result/zipError.md @@ -13,20 +13,20 @@ Result<'ok, 'leftError> -> Result<'ok, 'rightError> -> Result<'ok, 'leftError * ### Example 1 ```fsharp -let result = Result.zip (Ok 1) (Ok 2) +let result = Result.zipError (Ok 1) (Ok 2) // Ok 1 ``` ### Example 2 ```fsharp -let result = Result.zip (Ok 1) (Error "Bad") +let result = Result.zipError (Ok 1) (Error "Bad") // Ok 1 ``` ### Example 3 ```fsharp -let result = Result.zip (Error "Bad1") (Error "Bad2") +let result = Result.zipError (Error "Bad1") (Error "Bad2") // Error("Bad1", "Bad2") ``` diff --git a/gitbook/resultOption/mapError.md b/gitbook/resultOption/mapError.md new file mode 100644 index 00000000..39318ed9 --- /dev/null +++ b/gitbook/resultOption/mapError.md @@ -0,0 +1,30 @@ +## ResultOption.mapError + +Namespace: `FsToolkit.ErrorHandling` + +Function Signature: + +```fsharp +('errorInput -> 'errorOutput) -> Result<'ok option, 'errorInput> -> Result<'ok option, 'errorOutput> +``` + +## Examples + +### Example 1 + +From the [ResultOption.map](../resultOption/map.md#example-3) example, if we want to map the error part alone, we can do it as below: + +```fsharp +// string -> int +let getErrorCode (message: string) = + match message with + | "bad things happened" -> 1 + | _ -> 0 + +let result : Result = + Error "bad things happened" // Result + |> ResultOption.mapError getErrorCode // Result + +// Error 1 +``` + diff --git a/gitbook/task/apply.md b/gitbook/task/apply.md new file mode 100644 index 00000000..e57b9fad --- /dev/null +++ b/gitbook/task/apply.md @@ -0,0 +1,28 @@ +# Task.apply + +Namespace: `FsToolkit.ErrorHandling` + +Function Signature: + +```fsharp +Task<('a -> 'b)> -> Task<'a> -> Task<'b> +``` + +## Examples + +Take the following function for example + +```fsharp +// string -> int +let characterCount (s: string) = s.Length +``` + +### Example 1 + +```fsharp +let result = + Task.singleton "foo" // Task + |> Task.apply (Task.singleton characterCount) // Task + +// task { 3 } +``` diff --git a/gitbook/task/bind.md b/gitbook/task/bind.md new file mode 100644 index 00000000..a4b04b8b --- /dev/null +++ b/gitbook/task/bind.md @@ -0,0 +1,28 @@ +## Task.bind + +Namespace: `FsToolkit.ErrorHandling` + +Function Signature: + +```fsharp +('a -> Task<'b>>) -> Task<'a> -> Task<'b> +``` + +## Examples + +Note: Many use-cases requiring `bind` operations can also be solved using [the `task` computation expression](../task/ce.md). + +### Example 1 + +Continuing from the [Task.map2 example](../task/map2.md#example-1) and given the function + +```fsharp +let notifyFollowers : NotifyNewPostRequest -> Task +``` + +we can notify all followers using `Task.bind` as below: + +```fsharp +newPostRequestResult |> Task.bind notifyFollowers +``` + diff --git a/gitbook/task/bindV.md b/gitbook/task/bindV.md new file mode 100644 index 00000000..06dfbe47 --- /dev/null +++ b/gitbook/task/bindV.md @@ -0,0 +1,32 @@ +## Task.bindV + +Namespace: `FsToolkit.ErrorHandling` + +Like [Task.bind](../task/bind.md), but taking a `ValueTask<'a>` as input + +Function Signature: + +```fsharp +('a -> Task<'b>>) -> ValueTask<'a> -> Task<'b> +``` + +## Examples + +Note: Many use-cases requiring `bind` operations can also be solved using [the `task` computation expression](../task/ce.md). + +### Example 1 + +Continuing from the [Task.map2 example](../task/map2.md#example-1 and given the function + +```fsharp +let notifyFollowers : NotifyNewPostRequest -> Task +``` + +and assuming `newPostRequestResult` has type `ValueTask` + +we can notify all followers using `Task.bindV` as below: + +```fsharp +newPostRequestResult |> Task.bindV notifyFollowers +``` + diff --git a/gitbook/task/catch.md b/gitbook/task/catch.md new file mode 100644 index 00000000..56f4b782 --- /dev/null +++ b/gitbook/task/catch.md @@ -0,0 +1,38 @@ +## Task.catch + +Namespace: `FsToolkit.ErrorHandling` + +Creates a `Task` that attempts to execute the provided task, returning `Choice1Of2` with the result if the task completes without exceptions, or `Choice2Of2` with the exception if an exception is thrown. + +Function Signature: + +```fsharp +Task<'a> -> Task> +``` + +## Examples + +Given the function: + +```fsharp +let taskThrow () = + task { + failwith "something bad happened" + return Error "" + } +``` + +### Example 1 + +```fsharp +let result = Task.catch (Task.singleton 42) +// task { Choice1Of2(42) } +``` + +### Example 2 + +```fsharp +let result = Task.catch (taskThrow ()) +// task { Choice2Of2(exn("something bad happened")) } +``` + diff --git a/gitbook/task/ce.md b/gitbook/task/ce.md new file mode 100644 index 00000000..a5346d67 --- /dev/null +++ b/gitbook/task/ce.md @@ -0,0 +1,26 @@ +## Task Computation Expression + +Namespace: `FsToolkit.ErrorHandling` + +## Examples: + +### Example 1 + +Given a personId and an age, find a person and update their age. + +```fsharp +parseInt : string -> int +findPersonById : int -> Task +updatePerson : Person -> Task +``` + +```fsharp +// Task +let addResult = task { + let personId = parseInt "3001" + let age = parseInt "35" + let! person = findPersonById personId + let person = { person with Age = age } + do! updatePerson person +} +``` \ No newline at end of file diff --git a/gitbook/task/map.md b/gitbook/task/map.md new file mode 100644 index 00000000..2fb77dd9 --- /dev/null +++ b/gitbook/task/map.md @@ -0,0 +1,23 @@ +# Task.map + +Namespace: `FsToolkit.ErrorHandling` + +Apply a function to the value of a task. + +## Function Signature + +```fsharp +('input-> 'output) -> Task<'input> -> Task<'output> +``` + +## Examples + +### Example 1 + +```fsharp +Task.map (fun x -> x + 1) (Task.singleton 1) + +// task { 2 } +``` + + diff --git a/gitbook/task/map2.md b/gitbook/task/map2.md new file mode 100644 index 00000000..7209fbf8 --- /dev/null +++ b/gitbook/task/map2.md @@ -0,0 +1,51 @@ +## Task.map2 + +Namespace: `FsToolkit.ErrorHandling` + +Function Signature: + +```fsharp +('a -> 'b -> 'c) -> Task<'a> -> Task<'b> -> Task<'c> +``` + +## Examples + +Note: Many use-cases requiring `map` operations can also be solved using [the `task` computation expression](../task/ce.md). + +### Example 1 + +Given the functions + +```fsharp +getFollowerIds : UserId -> Task +createPost : CreatePostRequest -> Task +``` + +And the type + +```fsharp +type NotifyNewPostRequest = + { UserIds : UserId list + NewPostId : PostId } + static member Create userIds newPostsId = + {UserIds = userIds; NewPostId = newPostsId} +``` + +We can create a `NotifyNewPostRequest` using `Task.map2` as below: + +```fsharp +let createPostAndGetNotifyRequest (req : CreatePostRequest) = + // Task + let getFollowersResult = getFollowerIds req.UserId + + // Task + let createPostResult = createPost req + + // Task + let newPostRequestResult = + Task.map2 + NotifyNewPostRequest.Create getFollowersResult createPostResult + + // ... +``` + diff --git a/gitbook/task/map3.md b/gitbook/task/map3.md new file mode 100644 index 00000000..c0856b89 --- /dev/null +++ b/gitbook/task/map3.md @@ -0,0 +1,53 @@ +# Task.map3 + +Namespace: `FsToolkit.ErrorHandling` + +## Function Signature + +```fsharp +('a -> 'b -> 'c -> 'd) + -> Task<'a> + -> Task<'b> + -> Task<'c> + -> Task<'d> +``` + +## Examples + +Note: Many use-cases requiring `map` operations can also be solved using [the `task` computation expression](../task/ce.md). + +### Example 1 + +Let's assume that we have an `add` function that adds three numbers: + +```fsharp +// int -> int -> int -> int +let add a b c = a + b + c +``` + +And an another function that asynchronously retrieves an integer, say a person's age: + +```fsharp +type AccountId = int + +// AccountId -> Task +let getAge accountId = + task { + let ages = [ + (1, 19); + (2, 21); + (3, 34); + (4, 47); + (5, 55); + ] + return ages |> Map.ofList |> Map.find accountId + } +``` + +With the help of `Result.map3` function, we can now do the following: + +```fsharp +let summedAges = + Task.map3 add (getAge 1) (getAge 3) (getAge 5) + // task { 108 } +``` diff --git a/gitbook/task/mapV.md b/gitbook/task/mapV.md new file mode 100644 index 00000000..19a5a264 --- /dev/null +++ b/gitbook/task/mapV.md @@ -0,0 +1,21 @@ +# Task.map + +Namespace: `FsToolkit.ErrorHandling` + +Like [Task.map](../task/map.md), but taking a `ValueTask<'a>` as input + +## Function Signature + +```fsharp +('input-> 'output) -> ValueTask<'input> -> Task<'output> +``` + +## Examples + +### Example 1 + +```fsharp +Task.mapV (fun x -> x + 1) (ValueTask.FromResult(1)) + +// task { 2 } +``` diff --git a/gitbook/task/zip.md b/gitbook/task/zip.md new file mode 100644 index 00000000..1a1cbbe2 --- /dev/null +++ b/gitbook/task/zip.md @@ -0,0 +1,24 @@ +# Task.zip + +Namespace: `FsToolkit.ErrorHandling` + +Takes two tasks and returns a tuple of the pair + +## Function Signature + +```fsharp +Task<'left> -> Task<'right> -> Task<('left * 'right)> +``` + +## Examples + +### Example 1 + +```fsharp +let left = Task.singleton 123 +let right = Task.singleton "abc" + +Task.zip left right +// task { (123, "abc") } +``` + diff --git a/gitbook/taskOption/apply.md b/gitbook/taskOption/apply.md new file mode 100644 index 00000000..ec854052 --- /dev/null +++ b/gitbook/taskOption/apply.md @@ -0,0 +1,48 @@ +# TaskOption.apply + +Namespace: `FsToolkit.ErrorHandling` + +Function Signature: + +```fsharp +Task<('a -> 'b) option> -> Task<'a option> -> Task<'b option> +``` + +## Examples + +Take the following function for example + +```fsharp +// string -> int +let characterCount (s: string) = s.Length +``` + +### Example 1 + +```fsharp +let result = + TaskOption.some "foo" // Task + |> TaskOption.apply (TaskOption.some characterCount) // Task + +// task { Some 3 } +``` + +### Example 2 + +```fsharp +let result = + Task.singleton None // Task + |> TaskOption.apply (TaskOption.some characterCount) // Task + +// task { None } +``` + +### Example 3 + +```fsharp +let result : Task = + TaskOption.some "foo" // Task + |> TaskOption.apply (Task.singleton None) // Task + +// task { None } +``` diff --git a/gitbook/taskOption/bind.md b/gitbook/taskOption/bind.md new file mode 100644 index 00000000..5d517b17 --- /dev/null +++ b/gitbook/taskOption/bind.md @@ -0,0 +1,65 @@ +# TaskOption.bind + +Namespace: `FsToolkit.ErrorHandling` + +## Function Signature + +```fsharp +('input -> Task<'output option>) -> Task<'input option> -> Task<'output option> +``` + +## Examples + +Take the following function for example + +```fsharp +type Account = + { EmailAddress : string + Name : string } + +// string -> Task +let lookupAccountByEmail email = task { + let john = { EmailAddress = "john@test.com"; Name = "John Johnson" } + let jeff = { EmailAddress = "jeff@test.com"; Name = "Jeff Jefferson" } + let jack = { EmailAddress = "jack@test.com"; Name = "Jack Jackson" } + + // Just a map lookup, but imagine we look up an account in our database + let accounts = Map.ofList [ + ("john@test.com", john) + ("jeff@test.com", jeff) + ("jack@test.com", jack) + ] + + return Map.tryFind email accounts +} +``` + +### Example 1 + +```fsharp +let taskOpt : Task = + TaskOption.some "john@test.com" // Task + |> TaskOption.bind lookupAccountByEmail // Task + +// task { Some { EmailAddress = "john@test.com"; Name = "John Johnson" } } +``` + +### Example 2 + +```fsharp +let taskOpt : Task = + TaskOption.some "jerry@test.com" // Task + |> TaskOption.bind lookupAccountByEmail // Task + +// task { None } +``` + +### Example 3 + +```fsharp +let taskOpt : Task = + Task.singleton None // Task + |> TaskOption.bind lookupAccountByEmail // Task + +// task { None } +``` diff --git a/gitbook/taskOption/either.md b/gitbook/taskOption/either.md new file mode 100644 index 00000000..e7edbdf3 --- /dev/null +++ b/gitbook/taskOption/either.md @@ -0,0 +1,33 @@ +# TaskOption.either + +Namespace: `FsToolkit.ErrorHandling` + +## Function Signature + +Provide two functions to execute depending on the value of the option. If the option is `Some`, the first function will be executed. If the option is `None`, the second function will be executed. + +```fsharp +(onSome : 'T -> Task<'output>) + -> (onNone : Task<'output>) + -> (input : Task<'T option>) + -> Task<'output> +``` + +## Examples + +### Example 1 + +```fsharp +TaskOption.either (fun x -> task { x * 2 }) (task { 0 }) (TaskOption.some 5) + +// task { 10 } +``` + +### Example 2 + +```fsharp +TaskOption.either (fun x -> x * 2) (task { 0 }) None + +// task { 0 } +``` + diff --git a/gitbook/taskOption/map.md b/gitbook/taskOption/map.md new file mode 100644 index 00000000..7b45e40d --- /dev/null +++ b/gitbook/taskOption/map.md @@ -0,0 +1,30 @@ +# TaskOption.map + +Namespace: `FsToolkit.ErrorHandling` + +Apply a function to the value of a task option if it is `Some`. If the option is `None`, return `None`. + +## Function Signature + +```fsharp +('input -> 'output) -> Task<'input option> -> Task<'output option> +``` + +## Examples + +### Example 1 + +```fsharp +TaskOption.map (fun x -> x + 1) (TaskOption.some 1) + +// task { Some 2 } +``` + +### Example 2 + +```fsharp +TaskOption.map (fun x -> x + 1) (Task.singleton None) + +// task { None } +``` + diff --git a/gitbook/taskOption/others.md b/gitbook/taskOption/others.md new file mode 100644 index 00000000..199e7396 --- /dev/null +++ b/gitbook/taskOption/others.md @@ -0,0 +1,33 @@ +# Other TaskOption Functions + +## defaultValue + +Returns the contained value if Some, otherwise returns the provided value + +### Function Signature + +```fsharp +'a -> Task<'a option> -> Task<'a> +``` + +## defaultWith + +Returns the contained value if Some, otherwise evaluates the given function and returns the result. + +### Function Signature + +```fsharp +(unit -> 'a) -> Task<'a option> -> Task<'a> +``` + +## some + +Wraps the provided value in an Task<'a option> + +### Function Signature + +```fsharp +'a -> Task<'a option> +``` + + diff --git a/gitbook/taskOption/zip.md b/gitbook/taskOption/zip.md new file mode 100644 index 00000000..b88c1e21 --- /dev/null +++ b/gitbook/taskOption/zip.md @@ -0,0 +1,33 @@ +# TaskOption.zip + +Namespace: `FsToolkit.ErrorHandling` + +Takes two options and returns a tuple of the pair or None if either are None + +## Function Signature + +```fsharp +Task<'left option> -> Task<'right option> -> Task<('left * 'right) option> +``` + +## Examples + +### Example 1 + +```fsharp +let left = TaskOption.some 123 +let right = TaskOption.some "abc" + +TaskOption.zip left right +// task { Some (123, "abc") } +``` + +### Example 2 + +```fsharp +let left = TaskOption.some 123 +let right = TaskOption.singleton None + +TaskOption.zip left right +// task { None } +``` diff --git a/gitbook/taskResult/catch.md b/gitbook/taskResult/catch.md new file mode 100644 index 00000000..21305b6b --- /dev/null +++ b/gitbook/taskResult/catch.md @@ -0,0 +1,45 @@ +## TaskResult.catch + +Namespace: `FsToolkit.ErrorHandling` + +Catches exceptions and maps them to the Error case using the provided function. + +Function Signature: + +```fsharp +(exn -> 'a) -> Task> -> Task> +``` + +## Examples + +Given the function: + +```fsharp +let taskThrow () = + task { + failwith "an exception happened" + return Error "" + } +``` + +### Example 1 + +```fsharp +let result : Task> = TaskResult.catch (_.Message) (TaskResult.ok 42) +// task { Ok 42 } +``` + +### Example 2 + +```fsharp +let result : Task> = TaskResult.catch (_.Message) (TaskResult.error "something bad happened") +// task { Error "something bad happened" } +``` + +### Example 3 + +```fsharp +let result : Task> = TaskResult.catch (_.Message) (taskThrow ()) +// task { Error "an exception happened" } +``` + diff --git a/gitbook/taskResult/zip.md b/gitbook/taskResult/zip.md new file mode 100644 index 00000000..06e741fc --- /dev/null +++ b/gitbook/taskResult/zip.md @@ -0,0 +1,32 @@ +# TaskResult.zip + +Namespace: `FsToolkit.ErrorHandling` + +## Function Signature + +```fsharp +Task> -> Task> -> Task> +``` + +## Examples + +### Example 1 + +```fsharp +let result = TaskResult.zip (TaskResult.ok 1) (TaskResult.ok 2) +// task { Ok (1, 2) } +``` + +### Example 2 + +```fsharp +let result = TaskResult.zip (TaskResult.ok 1) (TaskResult.error "Bad") +// task { Error "Bad" } +``` + +### Example 3 + +```fsharp +let result = TaskResult.zip (TaskResult.error "Bad1") (TaskResult.error "Bad2") +// task { Error "Bad1" } +``` diff --git a/gitbook/taskResult/zipError.md b/gitbook/taskResult/zipError.md new file mode 100644 index 00000000..a358acfe --- /dev/null +++ b/gitbook/taskResult/zipError.md @@ -0,0 +1,32 @@ +# TaskResult.zipError + +Namespace: `FsToolkit.ErrorHandling` + +## Function Signature + +```fsharp +Task> -> Task> -> Task> +``` + +## Examples + +### Example 1 + +```fsharp +let result = TaskResult.zipError (TaskResult.ok 1) (TaskResult.ok 2) +// task { Ok 1 } +``` + +### Example 2 + +```fsharp +let result = TaskResult.zipError (TaskResult.ok 1) (TaskResult.error "Bad") +// task { Ok 1 } +``` + +### Example 3 + +```fsharp +let result = TaskResult.zipError (TaskResult.error "Bad1") (TaskResult.error "Bad2") +// task { Error("Bad1", "Bad2") } +``` diff --git a/gitbook/validation/map.md b/gitbook/validation/map.md new file mode 100644 index 00000000..4478da3d --- /dev/null +++ b/gitbook/validation/map.md @@ -0,0 +1,41 @@ +# Validation.map + +Namespace: `FsToolkit.ErrorHandling` + +`map` applies a transformation to the value inside a `Validation` if it represents a successful result (`Ok`). It allows you to perform a computation on the value while preserving the success/error status of the original `Validation`. If the original `Validation` is an `Error`, `map` does nothing and returns the same `Error` unchanged. + +## Function Signature + +```fsharp +('okInput -> 'okOutput) -> Validation<'okInput, 'error> -> Validation<'okOutput, 'error> +``` + +## Examples + +Take the following functions for example + +```fsharp +// string -> int +let remainingCharacters (prompt: string) = + 280 - prompt.Length +``` + +### Example 1 + +```fsharp +let validation = + Validation.ok "foo" // Validation + |> Validation.map remainingCharacters // Validation + +// Ok 277 +``` + +### Example 2 + +```fsharp +let result = + Validation.error "bad things happened" // Validation + |> Validation.map remainingCharacters // Validation + +// Error ["bad things happened"] +``` diff --git a/gitbook/validation/mapError.md b/gitbook/validation/mapError.md new file mode 100644 index 00000000..ad4b4cd0 --- /dev/null +++ b/gitbook/validation/mapError.md @@ -0,0 +1,44 @@ +# Validation.mapError + +Namespace: `FsToolkit.ErrorHandling` + +`mapError` takes a validation and a normal function and returns a new validation value based on the input error value and the function + +## Function Signature + +```fsharp +('errorInput -> 'errorOutput) -> Validation<'ok, 'errorInput> + -> Validation<'ok, 'errorOutput> +``` + +## Examples + +Take the following functions for example + +```fsharp +// string -> int +let getErrorCode (message: string) = + match message with + | "bad things happened" -> 1 + | _ -> 0 +``` + +### Example 1 + +```fsharp +let result = + Validation.ok "all good" // Validation + |> Validation.mapError getErrorCode // Validation + +// Ok "all good" +``` + +### Example 2 + +```fsharp +let result = + Validation.error "bad things happened" // Validation + |> Validation.mapError getErrorCode // Validation + +// Error [1] +``` diff --git a/gitbook/validation/mapErrors.md b/gitbook/validation/mapErrors.md new file mode 100644 index 00000000..f9c944aa --- /dev/null +++ b/gitbook/validation/mapErrors.md @@ -0,0 +1,44 @@ +# Validation.mapErrors + +Namespace: `FsToolkit.ErrorHandling` + +Similar to [Validation.mapError](../validation/mapError.md), except that the mapping function is passed the full list of errors, rather than each one individually. + +## Function Signature + +```fsharp +('errorInput list -> 'errorOutput list) -> Validation<'ok, 'errorInput> + -> Validation<'ok, 'errorOutput> +``` + +## Examples + +Take the following functions for example + +```fsharp +// string -> int +let getErrorCode (messages: string list) = + match messages |> List.tryFind ((=) "bad things happened") with + | Some _ -> [1] + | _ -> [0] +``` + +### Example 1 + +```fsharp +let result = + Validation.ok "all good" // Validation + |> Validation.mapErrors getErrorCode // Validation + +// Ok "all good" +``` + +### Example 2 + +```fsharp +let result : Validation = + Validation.error "bad things happened" // Validation + |> Validation.mapErrors getErrorCode // Validation + +// Error [1] +``` diff --git a/gitbook/validation/zip.md b/gitbook/validation/zip.md new file mode 100644 index 00000000..db527a9b --- /dev/null +++ b/gitbook/validation/zip.md @@ -0,0 +1,32 @@ +# Validation.zip + +Namespace: `FsToolkit.ErrorHandling` + +## Function Signature + +```fsharp +Validation<'leftOk, 'error> -> Validation<'rightOk, 'error> -> Validation<'leftOk * 'rightOk, 'error> +``` + +## Examples + +### Example 1 + +```fsharp +let result = Validation.zip (Validation.ok 1) (Validation.ok 2) +// Ok (1, 2) +``` + +### Example 2 + +```fsharp +let result = Validation.zip (Validation.ok 1) (Validation.error "Bad") +// Error [ "Bad" ] +``` + +### Example 3 + +```fsharp +let result = Validation.zip (Validation.error "Bad1") (Validation.error "Bad2") +// Error [ "Bad1"; "Bad2" ] +``` diff --git a/src/FsToolkit.ErrorHandling/TaskOption.fs b/src/FsToolkit.ErrorHandling/TaskOption.fs index b314b0f3..914ba271 100644 --- a/src/FsToolkit.ErrorHandling/TaskOption.fs +++ b/src/FsToolkit.ErrorHandling/TaskOption.fs @@ -55,7 +55,7 @@ module TaskOption = /// Gets the value of the option if the option is Some, otherwise returns the specified default value. /// /// The specified default value. - /// The input option. + /// The input option. /// /// The option if the option is Some, else the default value. /// @@ -67,7 +67,7 @@ module TaskOption = /// Gets the value of the option if the option is Some, otherwise evaluates and returns the result. /// /// A thunk that provides a default value when evaluated. - /// The input option. + /// The input option. /// /// The option if the option is Some, else the result of evaluating . ///