我正在编写一个异步 HTTP API 客户端模块/库。为了使一切尽可能 DRY,我试图从进行 API 调用的不同部分组合每个 HTTP API 调用,自下而上:构建请求,获取响应,将响应读取到字符串缓冲区,解析 JSON 内容将该字符串缓冲区放入一个对象中。
到目前为止,我有这个代码:
module ApiUtils =
// ... request builder fns omitted ...
let getResponse<'a> (request : Net.WebRequest) =
request.AsyncGetResponse()
let readResponse (response : Net.WebResponse) =
use reader = new StreamReader(response.GetResponseStream())
reader.AsyncReadToEnd()
let getString = getResponse >> (Async.flatMap readResponse)
let parseJson<'T> responseText : 'T =
Json.JsonConvert.DeserializeObject<'T> responseText
let getJson<'T> = getString >> (Async.map parseJson<'T>)
而且,如您所见,我用我自己的添加扩展了 Async 模块:
module Async =
let map f m =
async {
let! v = m
return f v
}
let flatMap f m =
async {
let! v = m
return! f v
}
我试图实现的目标是构建一个具有我可以在async
块中使用的功能的模块,以利用计算表达式语法的所有优势。我想知道我是否做得对,是否选择了正确的名字,等等。我几乎没有接受过正规的函数式编程教育,有时我什至不确定我是否知道自己在做什么。