gpt4 book ai didi

F# 自定义类型提供程序 - 多次调用 DefineStaticParameters InstantiationFunction

转载 作者:行者123 更新时间:2023-12-01 12:13:46 25 4
gpt4 key购买 nike

我有一个 F# 自定义类型提供程序(在本例中为 CheckedRegexProvider);相关来源是

[<TypeProvider>]
type public CheckedRegexProvider() as this =
inherit TypeProviderForNamespaces()

// Get the assembly and namespace used to house the provided types
let thisAssembly = Assembly.GetExecutingAssembly()
let rootNamespace = "Samples.FSharp.RegexTypeProvider"
let baseTy = typeof<obj>
let staticParams = [ProvidedStaticParameter("pattern", typeof<string>)]

let regexTy = ProvidedTypeDefinition(thisAssembly, rootNamespace, "RegexTyped", Some baseTy)

do regexTy.DefineStaticParameters(
parameters=staticParams,
instantiationFunction=(fun typeName parameterValues ->

match parameterValues with ...

然后我有一个简单的测试项目,我在 .fs 中放了一些琐碎的代码
open Samples.FSharp.RegexTypeProvider
type T = RegexTyped< @"(?<AreaCode>^\d{3})-(?<PhoneNumber>\d{3}-\d{4}$)">

令我困惑的是 instanceationFunction 被调用的次数比我预期的要多得多。我认为只有当我更改静态参数时才会调用该函数(在本例中为“(?^\d{3})-(?\d{3}-\d{4}$)”),而不是每次我在测试源中做了一些事情(例如按下空格键),那个 lambda 被连续调用两次。如果我真的更改参数,它会被调用两次或三次。

这当然会对 IDE(在我的情况下为 Visual Studio)产生很大影响,特别是因为该函数旨在提供一种可能需要扫描某些数据源以获取架构信息的类型。

然后,我尝试将类型提供程序调用隔离在单独的源模块文件(我们称之为 M1.fs)中,并在实际测试代码(M2.fs)中打开该模块。有了这个,lambda 仍然会在每次接触 M1.fs 时被调用,但是当我在 M2.fs 中工作时,它根本不会被调用,正如预期的那样。

我要问的是:那些对实例化函数的连续调用是否正确?这是设计使然吗?

如果是,为什么会这样?

最佳答案

类型提供程序在编译时被调用,然后编译器使用它们提供的类型来编译其余代码。

几乎每个智能处理 F# 代码的 IDE 都是通过在幕后调用 F# 编译器服务来构建 AST(通常一次一个源文件),然后对该 AST 执行操作以提供 Intellisense 等操作。

F# 编译器服务不会缓存以前编译的结果,因为您所做的任何更改都可能对源文件中的其他位置产生影响,无论是在它之前还是之后。该语句的“之后”部分是出于显而易见的原因,但为什么第 25 行的更改会影响第 10 行可能不是很明显。原因是类型推断:如果第 10 行是 let a = Array.zeroCreate 1024 ,第 25 行是 a.[0] <- 42 , 那么 a 的类型将被推断为 int[] .如果将第 25 行更改为 a.[0] <- "forty-two" , 那么 a 的类型将被推断为 string[] ,为第 10 行构建的 AST 会有所不同。因此,每次调用 F# 编译器服务都会重新编译整个源文​​件。

因此,每次编辑源文件时,F# 编译器服务都会重新编译该文件。如果该文件包含您的类型提供程序定义,则编译器必须实例化类型提供程序才能编译该文件,因此您的instantiationFunction每次编译文件时都必须调用。

所以是的,你看到的行为是设计使然。

关于F# 自定义类型提供程序 - 多次调用 DefineStaticParameters InstantiationFunction,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49784944/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com