【发布时间】:2018-11-20 04:37:19
【问题描述】:
我有一个Result<'T, 'E> list,我想按照以下规则将其转换为单个Result<'T list, 'E>:
- 如果任何
Result是Error,那么结果应该是Error - 如果结果是
Error,它应该是列表中的第一个Error - 如果每个结果都是
OK,那么结果应该是Ok,并且应该保持列表顺序
所以我试了一下,实现如下:
let all xs =
let folder = fun state next ->
match (state, next) with
| (Result.Ok ys, Result.Ok y) -> ys |> List.append [ y ] |> Result.Ok
| (Result.Error e, _) -> Result.Error e
| (_, Result.Error e) -> Result.Error e
Seq.fold folder (Result.Ok []) xs
但是,这似乎已经在标准库中实现了。有吗?
其次,我有一个Result 的计算表达式,如下所示:
type ResultBuilder () =
member this.Bind(x, f) =
match x with
| Result.Ok o -> f o
| Result.Error e -> Result.Error e
member this.Return(value) = Result.Ok value
member this.ReturnFrom(value) = value
let result = new ResultBuilder()
我可以在result { ... } 中使用all,但是否可以进一步集成?例如通过实现ResultBuilder.For?
【问题讨论】:
-
它不在 FSharpCore 中,但一些扩展库实现了该功能,在 F#+ 中,例如它被称为
sequence,它适用于任何 Traversable。