fsprojects / Chessie

Railway-oriented programming for .NET
http://fsprojects.github.io/Chessie/
The Unlicense
188 stars 43 forks source link

Add mergeErrors and collectErrors to Trial module #48

Closed iskandersierra closed 7 years ago

iskandersierra commented 7 years ago

Feature

This is not a problem but a feature I'm proposing. I don't know whether it can be easily reproduced with current functionality. I could make a PR if you want me to, but I wanted to ask here before going forward.

I have the following situation: I want to be able to collect a number of validation results in the form of Result<unit, ‘error> and obtain a condensed validation result of the same type.

So I would like to be able to do:

let result = trial {
    let validations = [ validate1; validate2; validate3; … ]
    return! Validations |> collectErrors
}

Where:

module Chessie.ErrorHandling.Trial
...
let mergeErrors result1 result2 =
    match result1, result2 with
    | Ok ((), errors1), Ok ((), errors2) ->
        Ok ((), errors1 @ errors2)
    | Ok ((), errors1), Bad (errors2)
    | Bad (errors1), Ok ((), errors2)
    | Bad (errors1), Bad (errors2) ->
        Bad (errors1 @ errors2)

let collectErrors = 
    Seq.reduce mergeErrors

It could be further generalized for collecting all results and errors. For example:

let mergeResults reducer result1 result2 =
    match result1, result2 with
    | Ok (r1, errors1), Ok (r2, errors2) ->
        Ok (reducer r1 r2, errors1 @ errors2)
    | Ok (_, errors1), Bad (errors2)
    | Bad (errors1), Ok (_, errors2)
    | Bad (errors1), Bad (errors2) ->
        Bad (errors1 @ errors2)

let collectResults reducer = 
    Seq.reduce (mergeResults reducer) 

Please direct me on the right direction if this does not make any sense, or indicate if you want me to start a PR.

Thanks