F# - 在编译时从字符串生成简单的空类型

jko*_*e27 3 string reflection f# static-typing compile-time

我想知道如果有可能生成一个字符串类似于一个简单的类提供商东西(录音或联盟,没有成员,只是匹配的名称与字符串名称),在编译时.

混合这个

http://www.readcopyupdate.com/blog/2014/09/18/faking-typeclasses-using-static-type-constraints.html

还有这个

从String创建区分联合案例

或记录类型的类似方法.

我想要获得的东西,例如(不一定采用相同的方法):

[<Literal>]
let myTypeName = "One"

type SingleStringTypeProvider = ... (here implementation)


type Provided = SingleStringTypeProvider<singleString>


let typeName = typeof<Provided.One>.Name
Run Code Online (Sandbox Code Playgroud)

最终结果:一个是编译时的类型(不是方法也不是函数)

编辑

正如在第一个答案中所建议的那样(非常感谢:)),我试图用提供的类型实现它,但是当我尝试从我的脚本文件中访问类型提供程序时我仍然很挣扎,显然我只看到创建的类型但是非类型提供者本身?

module SimpleStringProvider

open ProviderImplementation.ProvidedTypes
open Microsoft.FSharp.Core.CompilerServices

[<TypeProvider>]
type SingleStringTypeProvider (config : TypeProviderConfig) as this =
    inherit TypeProviderForNamespaces (config)

    let asm = System.Reflection.Assembly.GetExecutingAssembly()
    let ns = "SimpleStringProvider"
    let stringProvider = ProvidedTypeDefinition(asm, ns, "SingleStringTypeProvider", Some(typeof<obj>))

    // Define one static parameter with type name
    let parameter = ProvidedStaticParameter("TypeName", typeof<string>)
    do stringProvider.DefineStaticParameters([parameter], fun typeName args ->
    // Create the main type (this corresponds to `Provided`)    
    let resTy = ProvidedTypeDefinition(asm, ns, typeName, Some(typeof<obj>))

    // Add a nested type as a member using the name from the parameter
    let typeName = args.[0] :?> string
    ProvidedTypeDefinition(typeName, None)
    |> resTy.AddMember

    resTy )


[<assembly:TypeProviderAssembly>]
do ()
Run Code Online (Sandbox Code Playgroud)

这里是我的script.fsx文件中的代码,可能我正在犯一些愚蠢的错误.

#r @".\testType\SimpleStringProvider.dll"

open SimpleStringProvider

type x = SimpleStringProvider.SingleStringTypeProvider<"test">
Run Code Online (Sandbox Code Playgroud)

script.fsx文件中的错误

非泛型类型'SimpleStringProvider.SingleStringTypeProvider'不期望任何类型参数,但这里给出了1个类型参数

Tom*_*cek 5

您可以提供嵌套类型,这些类型可以基于静态参数.在您的示例中Provided是一个类型,Provided.One可以是嵌套类型.

为此,您可以编写如下内容:

[<TypeProvider>]
type public SingleStringTypeProvider(cfg:TypeProviderConfig) as this =
  inherit TypeProviderForNamespaces()

  // Generate namespace and the main type provider
  let asm = System.Reflection.Assembly.GetExecutingAssembly()
  let ns = "Samples"
  let stringProvider = ProvidedTypeDefinition(asm, ns, "SingleStringTypeProvider", Some(typeof<obj>))

  // Define one static parameter with type name
  let parameter = ProvidedStaticParameter("TypeName", typeof<string>)
  do stringProvider.DefineStaticParameters([parameter], fun typeName args ->
    // Create the main type (this corresponds to `Provided`)    
    let resTy = ProvidedTypeDefinition(asm, ns, typeName, Some typeof<IniFile>)

    // Add a nested type as a member using the name from the parameter
    let typeName = args.[0] :?> string
    ProvidedTypeDefinition(typeName, None)
    |> resTy.AddMember

    resTy )

[<assembly:TypeProviderAssembly>]
do()
Run Code Online (Sandbox Code Playgroud)

我没有测试过这个,所以你可能需要做一些调整,但我认为它应该可行.