A simple computational expression builder to work with Result<'a, 'b>.
You can use it to construct a Result from simple values (though that might not make much sense ;)
let value : Result<int, unit> = result {
return 0
} // Ok 0It can help, when working with the inner values of Result – for instance:
let value : Result<int, unit> = result {
let! a = Ok 1
let! b = Ok 2
return a + b
} // Ok 3The benefit is the handling of Error values:
let value : Result<int, string> = result {
let! a = Ok 1
let! b = Error "oh no :("
return a + b
} // Error "oh no :("
While the above examples can also be done with pattern matching, it gets trickier when working with collections.
The semantic of the ResultBuilder is, when processing a list of Result values, either there are only Ok values, and you get an Ok of a list of all values.
If there is at least one Error value, you get an Error of a list of all encountered errors.
For example:
let cs : Result<int, string> list = [
Ok 1
Ok 2
Ok 3
Error "4"
Ok 5
Error "6"
]
let a : Result<int list, string list> = result {
for (c : int) in cs do
yield c + 1
} // Error ["4"; "6"]
let a' = result {
for c in cs |> List.take 3 do
yield c + 1
} // Ok [2; 3; 4]for constructs do not have to iterate over a value of type Result:
let b = result {
for (i, c) in cs |> List.indexed do
let! c = c // c is now Result<int, string> and must be unwrapped
yield c + i
}Just copy the file into your Project, or use Pakets GitHub dependency feature and open FSharp.Control.Results.