F# quotation with spliced parameter of any type

136 Views Asked by At

I am trying to develop F# type provider.
It provides some DTOs (with the structure described in some external document) and a set of methods for processing them. The processing algorithm is based on reflection, and I want to have a single quotation representing it.
Generally, this algorithm must pass all method call arguments to the already written function serialize: obj -> MySerializationFormat, storing all results in a list, so I getting a value of MySerializationFormat list.

Code sample below shows, how I tried to do that for first time:

let serialize (value: obj) = ...
let processingCode: Expr list -> Expr = 
    fun args ->   
        let serializeArgExpr (arg: Expr) = <@ serialize %%arg} @>
        let argsExprs = List.map serializeArgExpr args
        let serializedArgList = 
            List.foldBack (fun head tail -> <@ (%head) :: (%tail)@>) argsExprs <@ [] @> 
        // futher processing

At that point I faced with exception: In function serializeArgExpr the actual type of value in arg: Expr may vary, it can be some primitive type (e.g string, int, float), or some provided type. The problem is %% operator treats that arg as an expression of the obj type. Type check is performed on that line in Microsoft.FSharp.Quotations.Patterns module, in function fillHolesInRawExpr.
So, as the actual type of my term not matched the treated type for "hole" in the quotation, it throws invalidArg.

I have tried several technics to avoid these exceptions with casting operations in my quotation, but they don't work. Then I found Expr.Coerce(source, target) function, which looks like solving my problem. I have changed the code of serializeArgExpr to something like that:

let serializeArgExpr (arg: Expr) =
    let value' = Expr.Coerce(value, typeof<obj>)
    <@ serialize %%value' } @>

Then faced a new strange exception:

The design-time type (point to a code line that uses my processingCode) utilized by a type provider was not found in the target reference assembly set

For me, it seems that my problem is to cast the type of value in any input Expr to an obj type. Thank you for diving in and trying to help.

0

There are 0 best solutions below