Mau*_*fer 12 f# type-providers
尝试使用类型提供程序对类型级别的peano数进行编码:
namespace TypeProviderPlayground
open System
open Microsoft.FSharp.Core.CompilerServices
open System.Runtime.CompilerServices
[<assembly: TypeProviderAssembly()>]
do()
type Z = class end
type 'a S = class end
type N = class end
[<TypeProvider>]
type PeanoProvider(s: TypeProviderConfig) =
let invalidate = Event<_,_>()
interface ITypeProvider with
member x.ApplyStaticArguments(typeWithoutArguments, typeNameWithArguments, staticArguments) =
let n : int = unbox staticArguments.[0]
[1..n] |> List.fold (fun s _ -> typedefof<S<_>>.MakeGenericType [| s |]) typeof<Z>
member x.GetNamespaces() =
let ns =
{ new IProvidedNamespace with
member x.GetNestedNamespaces() = [||]
member x.GetTypes() = [||]
member x.ResolveTypeName t =
if t = "N"
then typeof<N>
else null
member x.NamespaceName = "Peano" }
[| ns |]
member x.GetStaticParameters t =
let p =
{ new Reflection.ParameterInfo() with
member z.Name = "number"
member z.ParameterType = typeof<int> }
[| p |]
[<CLIEvent>]
member x.Invalidate = invalidate.Publish
member x.Dispose() = ()
member x.GetInvokerExpression(syntheticMethodBase, parameters) =
raise <| NotImplementedException()
Run Code Online (Sandbox Code Playgroud)
该N类型是只是一个虚拟的,否则我无法得到它要经过类型提供商.消费者代码:
open TypeProviderPlayground
[<Generate>]
type S<'a> = Peano.N<5>
Run Code Online (Sandbox Code Playgroud)
我收到这个错误:
error FS3152: The provider 'TypeProviderPlayground.PeanoProvider' returned a non-generated type
'TypeProviderPlayground.S`1[[TypeProviderPlayground.S`1[[TypeProviderPlayground.S`1[[TypeProviderPlayground.S`1[[TypeProviderPlayground.S`1[[TypeProviderPlayground.Z, TypeProviderPlayground, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], TypeProviderPlayground, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], TypeProviderPlayground, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], TypeProviderPlayground, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], TypeProviderPlayground, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]'
in the context of a [<Generate>] declaration. Either remove the [<Generate>] declaration or adjust the type provider to only return generated types.
Run Code Online (Sandbox Code Playgroud)
其中说类型是正确构造的(Z S S S S S)但由于某种原因,编译器不会接受它作为"生成类型".
如果我删除该[<Generated>]属性,我会收到一些其他错误,告诉我要添加它.
这是否意味着类型提供程序只能处理动态发出的类型(这在乍一看似乎是一个奇怪的要求)?
另外,如果我这样做:
[<Generate>]
type WW<'a> = Peano.N<5>
Run Code Online (Sandbox Code Playgroud)
我收到一个错误,说这WW'1是预期的但是S'1被退回了.为什么返回的类型(由类型提供者)必须匹配我在消费者中声明的类型名称?
kvb*_*kvb 15
有关类型提供程序的一些重要事项需要实现.首先,提供的类型有两种:
就像单挑一样,控制这种区别的机制仍然悬而未决.在预览中,您需要使用[<Generate>]嵌入了生成类型的程序集中的属性,并且[<Generate>]在使用已擦除的提供类型时不应使用该属性.我相信(但不能记得肯定的是)在提供的结束时生成的内容是根据类型的Assembly属性确定的.
另外,请记住,typeof<X>在实现API时,您不一定要使用实际类型(例如via ) - 您经常需要使用派生自的自定义类型System.Type.在不同的方法中必须满足许多不变量.原始类型提供程序API不容易使用 - 我建议等待一些使用更好的API包装器的示例(我希望在未来几周内发布).
话虽如此,从这里快速看一下,你当前的方法中至少有一些东西对我来说是错误的:
ApplyStaticArguments与参数名称不同typeNameWithArguments.大概这就是为什么你得到提到类型名称的错误.WW<'a>从非泛型类型(例如S<S<S<S<S<Z>>>>>)创建泛型类型(例如).| 归档时间: |
|
| 查看次数: |
2149 次 |
| 最近记录: |