[英]Clean way to extract results, or aggregate errors using Result, in f#
我有一個從網格收集數據的系統。 它按行組織。 處理的每一行都返回一個Result<data, string list>
object。 錯誤案例中的列表是解析過程中遇到的錯誤列表。 每行可以有多個錯誤,但只有一個有效結果。
如果沒有錯誤,我想將數據聚合到列表data list
中,或者如果至少有一個錯誤,我想在string list
表單中制作完整的錯誤列表。
最終返回類型為Result<data list, string list>
我有以下代碼:
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
)
)
但這感覺非常笨重且難以閱讀。
使用 Result<>,有沒有辦法:
您在這里要做的是折疊,這是一種迭代列表的所有元素的方法,同時保持某種 state 就像您 go 一樣。 在這種情況下, Ok
將是最終的結果值 - 所有值均正常或所有Error
均出錯。
折疊 function 將非常簡單:
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)
這個 function 同時查看“迄今為止累積的結果”(也稱為“狀態”)和當前項目,並針對四種可能性中的每一種,返回適當的新“迄今為止累積的結果”。
然后你可以使用這個 function 折疊列表,初始 state 是Ok []
:
gridRows |> List.fold f (Ok [])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.