I have a type provider which gives me the error "Type mismatch when splicing expression into quotation literal".
I extracted the code below in order to reproduce the issue in a smaller context.
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>
...and when I use the type provider like
let root = Provided.Root()
let a = root.SomeProperty
I get the error:
Error: The type provider 'typeproviders.providerpoc+MyProvider' reported an error in the context of provided type 'typeproviders.providerpoc.Provided.Root', member 'get_Menu'.
The error: Type mismatch when splicing expression into quotation literal.
The type of the expression tree being inserted doesn't match the type expected by the splicing operation.
Expected 'System.Object', but received type 'System.String'.
Consider type-annotating with the expected expression type, e.g., (%% x : string) or (%x : string).. Parameter name: receivedType.
How can I write the quotation to be able to call a function inside the quotation?
Thanks!
What the error message is saying is that you are putting a quoted expression of type obj
in a place where a quoted expression of type string
is expected.
I suspect this is happening when creating the GetterCode
in the provided property:
GetterCode = (fun args -> <@@ f %%(args.[0]) @@>)
Here, args
is an array of quoted expressions where each expression is of type obj
, but the function f
expects a string and so the quotation filling the hole using %%
should be of type string
Adding a type conversion that would turn the obj
into string
should do the trick:
GetterCode = (fun args -> <@@ f (unbox<string> (%%(args.[0]))) @@>)