.net 使用绑定到链连续函数
是F#4.1中的一项新功能:.net 使用绑定到链连续函数,.net,f#,functional-programming,monads,pipeline,.net,F#,Functional Programming,Monads,Pipeline,是F#4.1中的一项新功能: 我不完全确定Result的F#library函数是否实现了此处所需的所有功能-bind操作允许您按顺序组合多个操作,并在出现第一个错误时停止 在本例中,您希望运行两个可能的函数之一,然后执行两个操作并收集它们生成的错误。为此,您可能需要定义更多的Result函数。类似这样的操作可以实现(我更改了代码以收集错误列表): 现在,您可以按如下方式表达您的逻辑: let init data directoryPath = Result.either (fun
我不完全确定
Result
的F#library函数是否实现了此处所需的所有功能-bind
操作允许您按顺序组合多个操作,并在出现第一个错误时停止
在本例中,您希望运行两个可能的函数之一,然后执行两个操作并收集它们生成的错误。为此,您可能需要定义更多的Result
函数。类似这样的操作可以实现(我更改了代码以收集错误列表):
现在,您可以按如下方式表达您的逻辑:
let init data directoryPath =
Result.either
(fun () -> createDirectory directoryPath)
(fun () -> createDirectory2 directoryPath)
|> Result.bind (fun directory ->
Result.both (createFile directory directoryPath) (getPermissionType directory))
|> Result.map (fun (filePath, permissionType) ->
saveData data directory filePath permissionType))
这里解释了面向铁路的编程:我个人发现使用ROP时有点问题,原因是这里没有同源属错误类型。虽然我不能声称在写作方面接近斯科特,但也许你可以在这里找到一些价值:
let init data directoryPath =
(match createDirectory directoryPath with
| Ok directory -> Ok directory
| Error err1 ->
match createDirectory2 directoryPath with
| Ok directory -> Ok directory
| Error err2 -> Error (err1 + "; " + err2))
|> function
| Ok directory ->
match (createFile directory directoryPath), (getPermissionType directory) with
| Ok filePath, Ok permissionType ->
Ok (saveData data directory filePath permissionType)
| Error err1, Ok _ -> Error err1
| Ok _, Error err2 -> Error err2
| Error err1, Error err2 -> Error (err1 + "; " + err2)
| Error err -> err
module Result =
let either f1 f2 =
match f1 () with
| Ok res -> Ok res
| Error e1 ->
match f2 () with
| OK res -> Ok res
| Error e2 -> (e1 @ e2)
let both res1 res2 =
match res1, res2 with
| Ok r1, Ok r2 -> Ok (r1, r2)
| Error e1, Error e2 -> Error (e1 @ e2)
| Error e, _ | _, Error e -> Error e
let init data directoryPath =
Result.either
(fun () -> createDirectory directoryPath)
(fun () -> createDirectory2 directoryPath)
|> Result.bind (fun directory ->
Result.both (createFile directory directoryPath) (getPermissionType directory))
|> Result.map (fun (filePath, permissionType) ->
saveData data directory filePath permissionType))