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.