This is a tricky question! To understand why your code does not work, you need to clearly distinguish between two levels - at one level (meta), you are composing quotations and at the other level (base) you are running some code using data object.
The reason why your code does not work is that args
is a list of expressions at the meta-level and you are trying to iterate over it at the base-level. The iteration needs to happen at the meta-level.
One way to solve this is to do the iteration at the meta-level and generate a list of functions that call AddValue
for all arguments. Then you can compose the functions:
(fun args ->
// Given arguments [a0; a1; ...] Generate a list of functions:
//
// [ fun data -> data.AddValue 0 a0; data ]
// [ fun data -> data.AddValue 1 a1; data ... ]
args
|> List.mapi (fun i arg ->
<@ fun (data:DataObject) -> data.AddValue i (%%arg : string); data @>)
// Compose all the functions just by calling them - note that the above functions
// take DataObject, mutate it and then return it. Given [f0; f1; ...] produce:
//
// ... (f1 (f0 (new DataObject())))
//
|> List.fold (fun dobj fe -> <@ (%fe) (%dobj) @>) <@ new DataObject() @> )
This is fun to write, but it gets really complicated. In practice, you could make things a lot easier by adding AddValues
method to your data object (taking obj[]
) and using Expr.NewArray
to create a single array (at the base-level) containing the values of all the parameters (from the meta-level):
<@@ let d = new DataObject()
d.AddValues(%(Expr.NewArray(typeof<obj>, args)))
d @@>