尝试使用类型提供程序对类型级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()
N
类型只是一个虚拟的类型,否则我就无法通过类型提供程序。
使用者代码:open TypeProviderPlayground
[<Generate>]
type S<'a> = Peano.N<5>
我收到了这个错误信息:
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.
这段代码表明类型已经正确构造(Z S S S S S
),但是由于某些原因,编译器不会将其接受为“生成的类型”。
如果我删除[<Generated>]
属性,则会出现其他错误提示要求我添加该属性。
这是否意味着类型提供程序仅适用于动态发出的类型(这一要求乍一看似乎很奇怪)?
另外,如果我执行以下操作:
[<Generate>]
type WW<'a> = Peano.N<5>
我得到一个错误,说期望的是
WW'1
,但返回的却是 S'1
。为什么类型提供者返回的类型必须与消费者声明的类型名称匹配?