f# - 如何在函数内将静态参数传递给 f# 中的类型提供程序

标签 f# type-providers f#-data

我正在使用FSharp.Data typeproviders

我想创建一个具有参数的函数,用于设置typeprovider的示例字符串或文件位置。

let SyncIt url sample converter storer =
    async {
        url
        |> MakeRequestAsync 
        |> Async.RunSynchronously
        |> JsonProvider< sample >.Parse
        |> Seq.iter (converter >> storer)
    }

如果调用模块中的 JsonProvider

[<Literal>]
let sample = """{"name":"Peter","age":9}"""

type provider = JsonProvider<sample>

工作正常。为什么我不能将其作为参数传递?我知道这与编译时的引用清晰有关,但除了显式声明每个提供程序之外,无法弄清楚如何解决它。

最佳答案

函数不能将静态参数的值作为参数,因为该值必须在编译时确定。这意味着如果你写:

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

尽管如此,我并不完全清楚为什么这里需要类型提供程序。提供者的目的是为您提供良好的类型,您可以使用它们来访问具体的数据源。如果您converterstorer处理任何 JSON 数据文件,那么您可能只需使用 JSON parser (also in F# Data) 就能完成任务.

异步 block 。另外,请注意,您的代码并不是真正异步运行 - 要使其异步,您需要使用 let! 下载 URL操作:

let SyncIt url parser storer =
    async {
        let wc = new WebClient() 
        let! html = wc.AsyncDownloadString(url)
        parser html
        |> Seq.iter (converter >> storer)
    }

关于f# - 如何在函数内将静态参数传递给 f# 中的类型提供程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16897051/

相关文章:

java - Android Camera2 回调——图像似乎被裁剪

f# - JsonProvider "This is not a constant expression or valid custom attribute value"

functional-programming - 如何在不断变化的 Rest/JSON 端点上使用 F# 类型提供程序?

xml - F# XML 类型提供程序公共(public)元素

f# - 如何将字符串解析为任何 F# 数据?

winforms - F# 使用 Winforms DataVisualization 制作条形图

f# - TypeProvider 无法从 Expression 添加方法

c# - Akka.NET 可以在 F# 系统中创建 C# actor 吗?

json - 通过 JSONProvider 重用类型定义?

f# - Google 安全浏览返回 400 错误请求