値はコンパイル時に決定される必要があるため、関数は引数として静的パラメーターの値を取ることはできません。これは、次のように書くと次のことを意味します。
let [<Literal>] sample = """{"name":"Peter","age":9}"""
let parseHtml html = JsonProvider<sample>.Parse(html)
...コンパイラはそれsample
が定数であることを認識しているため(およびコンパイラはその値を認識しているため)、(コンパイル中に)型プロバイダーをインスタンス化して型を生成できるため、すべて問題ありません。次のようなものを書く場合:
let parseHtml sample html = JsonProvider<sample>.Parse(html)
...その後、コンパイラはsample
実行時に の値が何であるかを知ることができないため、コンパイル時に必要な型を生成できません。型プロバイダーは実行時に「存在」しないため、その場で型を生成することはできません (型プロバイダーのポイントは、コンパイル時の安全性の保証を提供することであるため、これはあまり役に立ちません)。
あなたの例。JsonProvider<sample>.Parse
あなたの場合、代わりに特定の関数を引数として取るのが理にかなっているかもしれません:
let SyncIt url parse storer =
async {
url
|> MakeRequestAsync
|> Async.RunSynchronously
|> parse
|> Seq.iter (converter >> storer)
}
このようにして、呼び出し元は静的パラメーターを型プロバイダーに指定し、関数を呼び出して同期を行うことができます。
let [<Literal>] sample = """{"name":"Peter","age":9}"""
SyncIt url (JsonProvider<sample>.Parse) storer
ただし、ここで型プロバイダーが必要な理由は完全にはわかりません。プロバイダーのポイントは、データの具体的なソースにアクセスするために使用できるナイス タイプを提供することです。converter
JSON データ ファイルでstorer
作業している場合は、 JSON パーサー (F# データでも)だけを使用して作業を完了できる可能性があります。
非同期ブロック。また、コードは実際には非同期で実行されていないことに注意してください。非同期にするには、let!
操作を使用して URL をダウンロードする必要があります。
let SyncIt url parser storer =
async {
let wc = new WebClient()
let! html = wc.AsyncDownloadString(url)
parser html
|> Seq.iter (converter >> storer)
}