如何将 F# 结果类型列表拆分为内部类型列表
How to split F# result type list into lists of inner type
我有一个list/sequence如下Result<DataEntry, exn> []
。此列表是通过根据一些用户输入并行调用多个 API 端点来填充的。
我不在乎某些调用是否失败,只要至少有 1 个调用成功即可。然后我需要对成功列表执行多个操作。
我的问题是如何将结果列表划分为 exn []
和 DataEntry []
列表。我尝试了以下方法:
// allData is Result<DataEntry, exn> []
let filterOutErrors (input: Result<DataEntry, exn>) =
match input with
| Ok v -> true
| _ -> false
let values, err = allData |> Array.partition filterOutErrors
这原则上满足要求,因为 values
包含所有成功案例,但可以理解的是,编译器无法推断类型,因此 values
和 err
都包含 Result<DataEntry, exn>
.
是否有任何方法可以拆分结果列表 Result<Success, Err>
,以便最终得到内部类型的单独列表?
你可以像这样提取好的和坏的。
let values =
allData
|> Array.choose (fun r ->
match r with
| Result.Ok ok -> Some ok
| Result.Error _ -> None)
let err =
allData
|> Array.choose (fun r ->
match r with
| Result.Ok _ -> None
| Result.Error error -> Some error)
您似乎对使用数组还是列表感到困惑。尽管您多次提到列表,但您在片段和问题文本中使用的 F# 代码都指向数组的使用。
最近有人建议我们在类型中使用 array
而不是 []
符号,因为 F# 使用符号 []
表示 [=有些地方是 14=],有些地方是 array
。还有用于数组的符号 [||]
,这可能会增加更多的混乱。
因此在这种情况下建议 Result<DataEntry,exn> array
。
Is there any way to split a list of result Result<Success, Err>
such that you end up with separate lists of the inner type?
记住Seq
/List
/Array
是可折叠的,所以你可以用fold
转换成Seq
/List
/ Array
的 'T
转换为任何其他类型 'S
。在这里你想从 []Result<DataEntry, exn>
转到例如元组 list<DataEntry> * list<exn>
。我们可以定义以下文件夹函数,它采用 list<'a> * list<'b>
类型的初始状态 s
和结果 Result<'a, 'b>
和 returns 你的列表元组 list<'a> * list<'b>
:
let listFolder s r =
match r with
| Ok data -> (data :: (fst s), snd s)
| Error err -> (fst s, err :: (snd s))
然后您可以按如下方式折叠数组:
let (values, err) = Seq.fold listFolder ([], []) allData
我有一个list/sequence如下Result<DataEntry, exn> []
。此列表是通过根据一些用户输入并行调用多个 API 端点来填充的。
我不在乎某些调用是否失败,只要至少有 1 个调用成功即可。然后我需要对成功列表执行多个操作。
我的问题是如何将结果列表划分为 exn []
和 DataEntry []
列表。我尝试了以下方法:
// allData is Result<DataEntry, exn> []
let filterOutErrors (input: Result<DataEntry, exn>) =
match input with
| Ok v -> true
| _ -> false
let values, err = allData |> Array.partition filterOutErrors
这原则上满足要求,因为 values
包含所有成功案例,但可以理解的是,编译器无法推断类型,因此 values
和 err
都包含 Result<DataEntry, exn>
.
是否有任何方法可以拆分结果列表 Result<Success, Err>
,以便最终得到内部类型的单独列表?
你可以像这样提取好的和坏的。
let values =
allData
|> Array.choose (fun r ->
match r with
| Result.Ok ok -> Some ok
| Result.Error _ -> None)
let err =
allData
|> Array.choose (fun r ->
match r with
| Result.Ok _ -> None
| Result.Error error -> Some error)
您似乎对使用数组还是列表感到困惑。尽管您多次提到列表,但您在片段和问题文本中使用的 F# 代码都指向数组的使用。
最近有人建议我们在类型中使用 array
而不是 []
符号,因为 F# 使用符号 []
表示 [=有些地方是 14=],有些地方是 array
。还有用于数组的符号 [||]
,这可能会增加更多的混乱。
因此在这种情况下建议 Result<DataEntry,exn> array
。
Is there any way to split a list of result
Result<Success, Err>
such that you end up with separate lists of the inner type?
记住Seq
/List
/Array
是可折叠的,所以你可以用fold
转换成Seq
/List
/ Array
的 'T
转换为任何其他类型 'S
。在这里你想从 []Result<DataEntry, exn>
转到例如元组 list<DataEntry> * list<exn>
。我们可以定义以下文件夹函数,它采用 list<'a> * list<'b>
类型的初始状态 s
和结果 Result<'a, 'b>
和 returns 你的列表元组 list<'a> * list<'b>
:
let listFolder s r =
match r with
| Ok data -> (data :: (fst s), snd s)
| Error err -> (fst s, err :: (snd s))
然后您可以按如下方式折叠数组:
let (values, err) = Seq.fold listFolder ([], []) allData