sdg*_*sdh 5 f# computation-expression
我有一个Result<'T, 'E> list我想Result<'T list, 'E>按照这些规则变成单一的:
Result,Error那么结果应该是ErrorError它应该是Error列表中的第一个OK则结果应为a,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
Run Code Online (Sandbox Code Playgroud)
但是,这似乎已经在标准库中实现了.有吗?
其次,我有一个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()
Run Code Online (Sandbox Code Playgroud)
我可以all在内部使用,result { ... }但可能进一步整合吗?例如通过实施ResultBuilder.For?
此功能由包提供FsToolkit.ErrorHandling。该函数List.sequenceResultM将返回:
Result.Ok的列表OkResult.Error仅包含第一个Error值还有一个变体List.sequenceResultA,它返回找到的所有错误的列表。
#r "nuget: FsToolkit.ErrorHandling, 2.0.0"
open FsToolkit.ErrorHandling
let xs : Result<int, string> list =
[
Ok 123
Ok 456
]
let xa = List.sequenceResultA xs // Ok [123; 456]
let xm = List.sequenceResultM xs // Ok [123; 456]
printfn "xa: %A" xa
printfn "xm: %A" xm
let ys =
[
Ok 123
Ok 456
Error "abc"
Ok 789
]
let ya = List.sequenceResultA ys // Error ["abc"]
let ym = List.sequenceResultM ys // Error "abc"
printfn "ya: %A" ya
printfn "ym: %A" ym
let zs =
[
Ok 123
Error "abc"
Error "def"
Ok 456
]
let za = List.sequenceResultA zs // Error ["abc"; "def"]
let zm = List.sequenceResultM zs // Error "abc"
printfn "za: %A" za
printfn "zm: %A" zm
Run Code Online (Sandbox Code Playgroud)
xa: Ok [123; 456]
xm: Ok [123; 456]
ya: Error ["abc"]
ym: Error "abc"
za: Error ["abc"; "def"]
zm: Error "abc"
Run Code Online (Sandbox Code Playgroud)
就计算表达式(也由 提供FsToolkit.ErrorHandling)而言,您可以这样做:
xa: Ok [123; 456]
xm: Ok [123; 456]
ya: Error ["abc"]
ym: Error "abc"
za: Error ["abc"; "def"]
zm: Error "abc"
Run Code Online (Sandbox Code Playgroud)
你有一个Result<'a, 'e> list想要的Result<'a list, 'e>.这听起来像https://fsharpforfunandprofit.com/posts/elevated-world-4/中sequence描述的功能(它与s 无关,尽管名称听起来像).快速检查https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/result.fs表明此功能尚未在标准FSharp.Core库中实现,因此您我需要自己实现它.seq
顺便说一句,如果你还没有读过Scott Wlaschin的"高架世界"系列,我不建议从中间开始我链接的文章.从本文开始,因为它构建了理解"遍历"和"序列"函数所需的背景知识.然后你就会知道实现其中一个函数的一般模式.
至于你的第二个问题,你能提供一些更具体的细节吗?例如,您想要出于什么行为ResultBuilder.For?for表达式所期望的正常行为是获取Result<'a, 'e> list(或seq或数组)并为Result<'a, 'e>列表或seq或数组中的每个内部块运行一次内部块.如果你试图在all这里使用你的函数,你会遇到类型不匹配Result<'a, 'e>(这是F#期望CE的.For方法产生的)以及Result<'a list, 'e>你的all方法返回的类型.具体到底你想用你的ResultBuilder.For方法做什么?
| 归档时间: |
|
| 查看次数: |
393 次 |
| 最近记录: |