非同期 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
、計算式の構文を最大限に活用するために、ブロックで使用できる関数を含むモジュールを構築することです。私はそれを正しく行っているかどうか、正しい名前を選択しているかどうかなどを疑問に思っていました.正式な関数型プログラミングの教育はほとんどまたはまったく受けていません。