【发布时间】:2026-01-22 23:55:02
【问题描述】:
来自 nodejs,我可以使用 Promises and then operator 链接异步事件,我正在尝试探索在惯用的 F# 中是如何完成的。
我试图链接的调用是对某个实体的 HTTP 休息调用,从创建到更新再到上传图像到发布。
函数组合表示一个函数的输出应该与要组合的第二个函数的输入相匹配,在我的例子中,公共输入和输出将是string,即 JSON 序列化字符串作为所有这些函数的输入和输出.
我了解到您可以使用 >> 运算符编写函数。理想情况下,函数不应该抛出错误,但是 IO 会发生一些事情,例如在这种情况下,如果我尝试创建的实体的 id 存在等等。
未知的问题是如果在链式序列中发生错误会发生什么,调用者如何知道哪里出了问题以及描述消息?操作可能会在链序列的中间或接近尾端或开始时失败。
我期望这些函数在出错时停止执行链并将错误消息返回给调用者。错误消息也是一个 JSON string,所以函数的输入和输出之间没有不兼容,所以你知道。
我也看了Choice,但不确定这是否是我应该去的方向。
代码不一定完整,我正在寻找的只是进一步研究以获得答案并可能改进这个问题的方向。这是一些开始的代码。
let create schema =
// POST request
"""{"id": 1, "title": "title 1"}""" // result output
let update schema =
// PUT request, update title
"""{"id": 1, "title": "title 2"}""" // output
let upload schema =
// PUT request, upload image and add thumbnail to json
"""{"id": 1, "title": "title 2", "thumbnail": "image.jpg"}"""
let publish schema =
// PUT request, publish the entity, add url for the entity
if response.StatusCode <> HttpStatusCode.OK then
"""{"code": "100", "message": "file size above limit"}"""
else
"""{"id": 1, "title": "title 2", "thumbnail": "image.jpg", "url": "http://example.com/1"}"""
let chain = create >> update >> upload >> publish
编辑 - 尝试
尝试在上传部分参数化图片缩略图
let create (schema: string) : Result<string,string> =
Ok """{"id": 1, "title": "title 1"}""" // result output
let update (schema: string) : Result<string,string> =
Ok """{"id": 1, "title": "title 2"}""" // output
let upload2 (img: string) (schema: string) : Result<string,string> =
printf "upload image %s\n" img
let statusCode = HttpStatusCode.OK
match statusCode with
| HttpStatusCode.OK -> Ok """{"id": 1, "title": "title 2", "thumbnail": "image.jpg"}"""
| x -> Error (sprintf "%A happened" x)
let publish (schema: string) =
let statusCode = HttpStatusCode.InternalServerError
match statusCode with
| HttpStatusCode.OK -> Ok """{"id": 1, "title": "title 2", "thumbnail": "image.jpg", "url": "http://example.com/1"}"""
| _ -> Error """{"code": "100", "message": "couldn't publish, file size above limit"}"""
let chain = create >> Result.bind update >> Result.bind (upload2 "image.jpg") >> Result.bind publish
【问题讨论】:
-
“Promises and then operator”实际上是穷人在 JavaScript 中实现的一元计算(但针对一种特定场景)。猜猜这个想法最初是从哪里来的? :-)
-
:) 是的,它有不足之处,顺便说一下,这是基于给定答案的单子吗?我读过,但仍在努力理解
-
是的,这或多或少就是 monad。
-
感谢您的确认,所以换句话说monad是一个接受单个输入并返回单个输出的函数的管道,并且由于任何阶段的错误,控制返回给调用者的错误或成功后的结果?
-
请不要将您的问题变成讨论区。这不是 * 的格式。如果您有更多问题,请随时单独发布。
标签: error-handling f# method-chaining function-composition