如何从类型提供程序中的调用引用中调用函数?

时间:2017-02-03 15:04:50

标签: f# type-providers quotations

我有一个类型提供程序,它给出了错误“将表达式拼接到引号文字时类型不匹配”。

我提取了下面的代码,以便在较小的上下文中重现该问题。

let f (s : string) : string = s //some dummy implementation

let t = ProvidedTypeDefinition(asm, ns, "Root", Some typeof<obj>)
let ctor = ProvidedConstructor(parameters = [],
                               InvokeCode = (fun args -> <@@ "root" :> obj @@>)) :> MemberInfo

let prop = ProvidedProperty(propertyName = "SomeProperty",
                            parameters = [],
                            propertyType = typeof<string>,
                            GetterCode = (fun args -> <@@ f %%(args.[0]) @@>)) :> MemberInfo

do  t.AddMembers [ctor; prop]
    t.SetBaseType typeof<obj>

...当我使用像

这样的类型提供者时
let root = Provided.Root()

let a = root.SomeProperty

我收到错误:

  

错误:类型提供程序'typeproviders.providerpoc + MyProvider'在提供的类型的上下文中报告错误   'typeproviders.providerpoc.Provided.Root',成员'get_Menu'。

     

错误:将表达式拼接到引号时键入不匹配   文字。

     

要插入的表达式树的类型不匹配   拼接操作所期望的类型。

     

预期'System.Object',但收到类型'System.String'。

     

考虑使用预期的表达式类型进行类型注释,例如(%% x:   string)或(%x:string)..参数名称:receivedType。

如何编写引文以便能够在引号内调用函数?

谢谢!

1 个答案:

答案 0 :(得分:6)

错误消息的含义是您在类型为obj的引用表达式的位置放置了string类型的引用表达式。

我怀疑在提供的属性中创建GetterCode时会发生这种情况:

GetterCode = (fun args -> <@@ f %%(args.[0]) @@>)

这里,args是一个带引号的表达式数组,其中每个表达式的类型为obj,但函数f需要一个字符串,因此使用{{1填充空洞的引号应该是%%

类型

添加将string转换为obj的类型转换应该可以解决问题:

string