Rem*_*mko 3 f# type-providers f#-data
我正在使用FSharp.Data typeproviders。
我想制作一个具有参数的函数,该参数设置typeprovider's示例字符串或文件位置。
let SyncIt url sample converter storer =
async {
url
|> MakeRequestAsync
|> Async.RunSynchronously
|> JsonProvider< sample >.Parse
|> Seq.iter (converter >> storer)
}
Run Code Online (Sandbox Code Playgroud)
如果使用以下命令调用模块中的JsonProvider
[<Literal>]
let sample = """{"name":"Peter","age":9}"""
type provider = JsonProvider<sample>
Run Code Online (Sandbox Code Playgroud)
工作正常。为什么我不能通过它parameter?我知道它与在编译时清楚引用有关,但是除了声明每个引用之外,其他所有方法都无法解决providers explicitly。
函数不能将静态参数的值作为参数,因为该值必须在编译时确定。这意味着如果您编写:
let [<Literal>] sample = """{"name":"Peter","age":9}"""
let parseHtml html = JsonProvider<sample>.Parse(html)
Run Code Online (Sandbox Code Playgroud)
...一切都很好,因为编译器知道这sample是一个常量(编译器知道其值),因此可以实例化类型提供程序(在编译过程中)以生成类型。如果您编写如下内容:
let parseHtml sample html = JsonProvider<sample>.Parse(html)
Run Code Online (Sandbox Code Playgroud)
...然后编译器无法知道sample运行时的值,因此无法在编译时生成所需的类型。类型提供程序在运行时不会“存在”,因此无法即时生成类型(这不会真正有用,因为类型提供程序的目的是为您提供一些编译时安全性保证)。
你的例子。在您的情况下,将特定JsonProvider<sample>.Parse函数作为参数可能是有意义的:
let SyncIt url parse storer =
async {
url
|> MakeRequestAsync
|> Async.RunSynchronously
|> parse
|> Seq.iter (converter >> storer)
}
Run Code Online (Sandbox Code Playgroud)
这样,调用者可以为类型提供者指定静态参数,然后调用您的函数进行同步:
let [<Literal>] sample = """{"name":"Peter","age":9}"""
SyncIt url (JsonProvider<sample>.Parse) storer
Run Code Online (Sandbox Code Playgroud)
虽然,对我来说还不是很清楚,为什么在这里需要类型提供者。提供程序的重点是为您提供可用于访问具体数据源的漂亮类型。如果你converter和storer对工作的任何 JSON数据文件,那么你可能能够获得使用刚刚做的事情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)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
817 次 |
| 最近记录: |