I have a system where I collect data from a grid. It is organized in rows.
Each row processed returns a Result<data, string list> object.
The list in the error case is a list of errors encountered during the parsing. Each row can have multiple errors, but only one valid result.
I would like to aggregate the data to a list data list if there are no errors, or make a complete list of errors, in the string list form if there is at least one error.
The final return type is Result<data list, string list>
I have the following code:
let hasErrors =
gridRows |> List.exists (fun r -> match r with | Ok _ -> false | Error _ -> true)
// build the layer list, or return the errors
match hasErrors with
| false -> Ok (
gridRows
|> List.map (fun r ->
match r with
| Ok layer -> layer
| Error _ -> failwith "this should never execute"
)
)
| true -> Error (
gridRows
|> List.collect (fun r ->
match r with
| Ok _ -> []
| Error messages -> messages
)
)
Run Code Online (Sandbox Code Playgroud)
But this feels very clunky and hard to read.
Using Result<>, is there a way to do:
您在这里要做的是折叠,这是一种迭代列表中所有元素的方法,同时保持某种状态。这种情况下的状态将是最终结果值 -Ok包含所有值或Error包含所有错误。
折叠功能非常简单:
let f state item =
match state, item with
| Ok prevResults, Ok res -> Ok (prevResults @ [res])
| Ok _, Error errs -> Error errs
| Error errs, Ok _ -> Error errs
| Error prevErrs, Error errs -> Error (prevErrs @ errs)
Run Code Online (Sandbox Code Playgroud)
该函数查看“到目前为止累积的结果”(也称为“状态”)和当前项目,并且对于四种可能性中的每一种,返回适当的新的“到目前为止累积的结果”。
然后你可以使用这个函数来折叠列表,初始状态是Ok []:
gridRows |> List.fold f (Ok [])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
888 次 |
| 最近记录: |