Skip to content

Commit

Permalink
docs: sequenceResultM
Browse files Browse the repository at this point in the history
  • Loading branch information
bartelink committed Feb 15, 2024
1 parent 621f36b commit ea8959c
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 5 deletions.
3 changes: 3 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
### 4.16.0
- [refactor!: Seq.sequenceResultM returns Array instead of seq](https://github.com/demystifyfp/FsToolkit.ErrorHandling/pull/255) [@bartelink](https://github.com/bartelink)

### 4.15.1 - January 15, 2024
- [Doc updates](https://github.com/demystifyfp/FsToolkit.ErrorHandling/pull/247) Credits @1eyewonder

Expand Down
2 changes: 2 additions & 0 deletions gitbook/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
* [sequenceResultM](list/sequenceResultM.md)
* [traverseResultA](list/traverseResultA.md)
* [sequenceResultA](list/sequenceResultA.md)
* Seqs
* [sequenceResultM](seq/sequenceResultM.md)
* Transforms
* [ofChoice](result/ofChoice.md)

Expand Down
69 changes: 69 additions & 0 deletions gitbook/seq/sequenceResultM.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Seq.sequenceResultM

Namespace: `FsToolkit.ErrorHandling`

## Function Signature

```fsharp
seq<Result<'a, 'b>> -> Result<'a[], 'b>
```

This is monadic, stopping on the first error. Compare the example below with [sequenceResultA](sequenceResultA.md).

See also Scott Wlaschin's [Understanding traverse and sequence](https://fsharpforfunandprofit.com/posts/elevated-world-4/).

## Examples

### Example 1

```fsharp
// string -> Result<int, string>
let tryParseInt str =
match Int32.TryParse str with
| true, x -> Ok x
| false, _ -> Error $"unable to parse '{str}' to integer"
["1"; "2"; "3"]
|> Seq.map tryParseInt
|> Seq.sequenceResultM
// Ok [| 1; 2; 3 |]
seq { "1"; "foo"; "3"; "bar" }
|> Seq.map tryParseInt
|> Seq.sequenceResultM
// Error "unable to parse 'foo' to integer"
```

### Example 2

```fsharp
// int -> Result<bool, string>
let isPrime (x: int) =
if x < 2 then Error $"{x} must be greater than 1"
elif x = 2 then Ok true
else
let rec isPrime' (x : int) (i : int) =
if i * i > x then Ok true
elif x % i = 0 then Ok false
else isPrime' x (i + 1)
isPrime' x 2
// int seq -> Result<bool, string list>
let checkIfAllPrime (numbers: seq<int>) =
numbers
|> Seq.map isPrime // Result<bool, string> list
|> Seq.sequenceResultM // Result<bool list, string>
|> Result.map (Array.forall id) // shortened version of '|> Result.map (fun bools -> bools |> Array.forall (fun x -> x = true))'
let a = [ 1; 2; 3; 4; 5 ] |> checkIfAllPrime
// Error [| "1 must be greater than 1" |]
let b = [| 1; 2; 3; 4; 5; 0 |] |> checkIfAllPrime
// Error [| "1 must be greater than 1" |]
let a = seq { 2; 3; 4; 5 } |> checkIfAllPrime
// Ok false
let a = [2; 3; 5;] |> checkIfAllPrime
// Ok true
```
10 changes: 5 additions & 5 deletions tests/FsToolkit.ErrorHandling.Tests/Seq.fs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ open Fable.Mocha
#if !FABLE_COMPILER
open Expecto
#endif
open FsToolkit.ErrorHandling
open SampleDomain
open TestData
open FsToolkit.ErrorHandling

let sequenceResultMTests =
testList "Seq.sequenceResultM Tests" [
testCase "sequenceResult with an empty sequence"
testCase "empty sequence"
<| fun _ ->
let tweets = Seq.empty
let expected = Ok [||]
Expand All @@ -24,7 +24,7 @@ let sequenceResultMTests =

Expect.equal actual expected "Should have an empty list of valid tweets"

testCase "sequenceResult with a sequence of valid data"
testCase "valid data"
<| fun _ ->
let tweets =
seq {
Expand All @@ -39,7 +39,7 @@ let sequenceResultMTests =

Expect.equal actual expected "Should have a list of valid tweets"

testCase "sequenceResult with few invalid data"
testCase "valid and invalid data"
<| fun _ ->
let tweets =
seq {
Expand All @@ -54,7 +54,7 @@ let sequenceResultMTests =

Expect.equal actual expected "traverse the sequence and return the first error"

testCase "sequenceResult stops after first invalid data"
testCase "stops after first invalid data"
<| fun _ ->
let mutable counter = 0

Expand Down

0 comments on commit ea8959c

Please sign in to comment.